5

型として宣言された特定のメソッド パラメーターを持つ C# インターフェイスがありobjectます。ただし、渡される実際の型は、インターフェイスを実装するクラスによって異なる場合があります。

public interface IMyInterface
{
    void MyMethod(object arg);
}

public class MyClass1 : IMyInterface
{
    public void MyMethod(object arg)
    {
        MyObject obj = (MyObject) arg;
        // do something with obj...
    }
}

public class MyClass2 : IMyInterface
{
    public void MyMethod(object arg)
    {
        byte[] obj = (byte[]) arg;
        // do something with obj...
    }
}

byte[]MyClass2 の問題は、 to と fromの変換が boxing と unboxing であることですobjectこれは、パフォーマンスに影響を与える計算コストの高い操作です。

この問題を汎用インターフェイスで解決すると、ボックス化/ボックス化解除が回避されますか?

public interface IMyInterface<T>
{
    void MyMethod(T arg);
}

public class MyClass1 : IMyInterface<MyObject>
{
    public void MyMethod(MyObject arg)
    {
        // typecast no longer necessary
        //MyObject obj = (MyObject) arg;
        // do something with arg...
    }
}

public class MyClass2 : IMyInterface<byte[]>
{
    public void MyMethod(byte[] arg)
    {
        // typecast no longer necessary
        //byte[] obj = (byte[]) arg;
        // do something with arg...
    }
}

これは .NET と Mono でどのように実装されていますか? どちらのプラットフォームでもパフォーマンスへの影響はありますか?

ありがとうございました!

4

6 に答える 6

14

.NET と同じメリットが Mono でも得られます。

ジェネリックは 1.9 で成熟したもののみをサポートするため、一般に Mono 1.9 または Mono 2.0 RCx を使用することを強くお勧めします。

于 2008-09-26T14:54:18.457 に答える
11

MyClass2 の問題は、byte[] と object 間の変換がボックス化とボックス化解除であり、これはパフォーマンスに影響を与える計算コストの高い操作であることです。

値型要素を持つものであっても、配列型に関連するボックス化はありません。配列は参照型です。

(byte[]) 引数のオーバーヘッドはせいぜい最小限です。

于 2008-09-26T14:50:07.110 に答える
8

モノでどのように実装されているかはわかりませんが、コンパイラは使用される異なる型ごとに特定の型の新しい関数を作成するため、ジェネリック インターフェイスが役立ちます (内部的には、生成された同じ関数を利用できる場合がいくつかあります)。 . 特定のタイプの関数が生成される場合、そのタイプをボックス化/ボックス化解除する必要はありません。

これが、Collections.Generic ライブラリが .NET 2.0 で大ヒットした理由です。これは、コレクションがボックス化を必要としなくなり、大幅に効率化されたためです。

于 2008-09-26T14:51:19.557 に答える
2

はい、.Net (MS は mono については不明) ジェネリックはコンパイル時に実装されるため、ボックス化やボックス化解除はまったく行われません。バックグラウンドでキャストを実行するだけのシンタックスシュガーであるJavaジェネリックとは対照的です(少なくとも一度はこの方法でした)。ジェネリックの主な問題は、ジェネリック コンテナーをポリモーフィックに扱うことができないことですが、それはトピックから少し外れています :-)

于 2008-09-26T15:33:57.940 に答える
1

Mono と話すことはできませんが、汎用インターフェイスを使用すると、MS ランタイムでのボックス化/ボックス化解除の問題が解決するはずです。

于 2008-09-26T14:50:20.153 に答える
0

mono の最新バージョンを使用している場合は、可能であれば 2.0 を使用してください。

Mono でのジェネリック インターフェイスのパフォーマンスは、通常のインターフェイス ディスパッチと組み合わせると非常に優れています。

一般的な仮想メソッドのディスパッチ [1] は、リリースされたすべての mono のバージョンでひどく、1.9 thhou で改善されました。

ジェネリック仮想メソッドのパフォーマンスの問題は、今年の終わりに予定されている mono の次のリリース (2.2) で修正されているため、問題はそれほど悪くはありません。

[1] 一般的な仮想メソッドは次のようなものです。

パブリック インターフェイス Foo {

  void Bla<T> (T a, T b);

}

于 2008-10-06T22:20:35.623 に答える