2

私はいくつかのコードをJavaからC#に翻訳することに取り組んでいますが、いくつかの問題を抱えています。

私はJavaで広く使われている匿名インターフェースの実装を複製しようとして問題がありますが、その方法がわかりません。

例は次のとおりです。

List<DATA> queue1 = new ArrayList<DATA>(dataSet);
            // Sort by distance to the first promoted data
            Collections.sort(queue1, new Comparator<DATA>() {
                @Override
                public int compare(DATA data1, DATA data2) {
                    double distance1 = distanceFunction.calculate(data1, promoted.first);
                    double distance2 = distanceFunction.calculate(data2, promoted.first);
                    return Double.compare(distance1, distance2);
                }
            });


  • 1)何を試しましたか? 2)何が推進されていますか? 3)このコードで何をしたいですか? - IronMan84
  • 1つの大きな違いはそれですクラスJavaでは匿名ですが、方法C#では匿名です。下の答えは良いです - あなたがJavaコードが複数のメンバを持つインタフェースを実装しているのを見るなら、対応する匿名メソッド(すなわちデリゲート)が同じクラスにあるかどうかはあなた次第です。 。 - prprcupofcoffee

5 답변


5

Javaで広く使われているインライン関数を複製しようとして問題があります

これらはインライン関数ではなく、特定のインタフェースを実装する無名クラスです。

C#が提供する代表者インラインまたは別の関数で定義できます。

これは、並べ替えの例です。List<DATA>を使用して所定の位置にComparison<T>代表者:

List<DATA> queue = new List<DATA>();
queue.Sort(
    (left, right) => {
        double distance1 = distanceFunction.Calculate(left, promoted.first);
        double distance2 = distanceFunction.Calculate(right, promoted.first);
        return Double.Compare(distance1, distance2);
    }
);

これが機能するためには、distanceFunctionあなたが呼び出す場所で変数がスコープ内にある必要があります。queue.Sort。呼び出しポイントより上で定義されたローカル変数、または呼び出しを行う関数を囲むクラスのメンバー変数/プロパティにすることができます。


  • +1。匿名クラスを許可しないのと同じ理由で、C#が静的でない内部クラスも許可しないことも注目に値します。 - Brian
  • @ブライアン:「非静的内部クラス」とはどういう意味ですか。許可されていませんか?以下は有効なコードです。public class Outer { private class Inner { } } - Daniel Hilgarth
  • しかしInnerC#では常に静的です。つまり、暗黙的に参照されていません。Outer。参照は、内部クラスのフィールドを介して明示的に指定する必要があります。実際、非静的内部クラスおよび匿名クラスにおけるJavaの暗黙の参照は、多くの場合、Javaコードのメモリリークの原因となります。 - Brian
  • @ DanielHilgarthああ、そのとき意味論の違い。静的とは、メソッドではなくクラス宣言を参照するという意味です。私が意味したのはprivate class InnerC#では、と同じです。private static class InnerJavaで。いずれにせよ、まだ良い答えです。 - Brian
  • @DanielHilgarth Javaと呼ばれるもの静的内部クラスそしてC#が何を呼ぶのか静的クラスC#では、静的でないクラスのみをインスタンス化でき、IIRCのネストしたクラスは静的にはできません。 Javaでは、静的メンバークラスはC#のネストされたクラスと同じですが、非静的メンバークラスはその中でインスタンス化されたオブジェクトへの参照を保持します。 C#にはアナログはありませんが、参照を維持することで簡単にエミュレートできます。Outer内部のインスタンスInnerオブジェクトを参照し、参照をOuterの中にInnerのコンストラクタです。 - dasblinkenlight

1

C#では、場合によってはインタフェースの代わりにデリゲートを使用することになります。特に、このように呼び出し元がメソッドをインラインで定義したい場合は特にそうです。ラムダを使用して、デリゲートが期待される場所にインラインで匿名メソッドを定義できます。

List<String> list = new List<String> { "B", "D", "E" };

list.Sort((a, b) => a.CompareTo(b));

C#でのJavaの匿名インターフェースの実装に相当するものはないので、必要なインターフェースがある場合(これはListそれを実装するには名前付きクラスを作成する必要があります。


0

C#は、匿名インターフェイスの実装の代わりにデリゲートの概念を使用しています。

交換したと仮定ArrayList<DATA>ネットでList<DATA>

IEnumerable<DATA> sorted =
    queue1.OrderBy(q => distanceFunction.calculate(q, promoted.first));


0

c#にList of Dataオブジェクトがあるとします。

queue1.OrderBy(a => distanceFunction.Calculate(a, promoted.First));


  • ここでは、リストを変更するのではなく、前のコレクションに基づいて新しいコレクションを作成していることに注意してください。あなたが使用する必要があるでしょうList.Sortリスト自体を変更する。 - Servy

0

元のJavaと同等のものが必要な場合は、次のようにします。

internal virtual void test()
{
    List<int> queue1 = new List<int>(dataSet);
    queue1.Sort(new ComparatorAnonymousInnerClassHelper());
}

private class ComparatorAnonymousInnerClassHelper : IComparer<int>
{
    public virtual int compare(int data1, int data2)
    {
        double distance1 = distanceFunction.calculate(data1, promoted.first);
        double distance2 = distanceFunction.calculate(data2, promoted.first);
        return distance1.CompareTo(distance2);
    }
}


  • これは匿名のインターフェイス実装でも匿名のものでもありません... - Servy
  • これはC#に相当するものです。なぜ匿名と呼ばれる必要があると思われるのですか。 - Dave Doknjas
  • 正確なC#に相当するものはありません。匿名インターフェースの実装を作成するためのC#のメカニズムはありません。最も近いメカニズム、つまりOPがJavaで使用している代わりに一般的に使用されているメカニズムは、名前付きインターフェースの実装ではなく、無名メソッドです。 - Servy
  • 試してみると、同じように機能することがわかります。これは、Javaが舞台裏で行うことを明示的に示しているに過ぎません。 - Dave Doknjas
  • はい私は同意する。しかし、私はコード変換の観点から見ています。Javaでの匿名インターフェースの実装を考えれば、C#で同じ結果を得る最も痛みのない方法は、隠された実装クラスを非匿名にすることです。 - Dave Doknjas

リンクされた質問


関連する質問

最近の質問