4

以下のクラス「混乱」の2つのメソッドは同じですか?

class MyClass
{
    public override string ToString()
    {
        return "I am confused now";
    }
}

class Confused
{    
    public MyClass GetMyClass()
    {
        return new MyClass();
    }

    public T GetMyClass<T>() where T : MyClass, new()
    {
        return System.Activator.CreateInstance<T>();
    }
}

class Program
{
    static void Main()
    {
        Confused c = new Confused();
        System.Console.WriteLine(c.GetMyClass());
        System.Console.WriteLine(c.GetMyClass<MyClass>());
    }
}

それらは異なるILを生成しますが、同僚を混乱させる以外に、「ストレートアップ」バージョン以外の汎用バージョンを作成する理由はあります:)

4

8 に答える 8

4

汎用バージョンを作成すると、派生クラスをインスタンス化して返すことができます。

where T : MyClass

また、ジェネリック バージョンでは、アクティベーション コードは必要ありません。

return new T();

これは、次のように指定したためです。

where T : new()

パラメーターなしのパブリック コンストラクターを強制する一般的な制約。

于 2011-07-14T14:28:00.340 に答える
2

確かに違いはあります。MyClass から派生した 2 番目のクラスがあるとします。

class MyClass2 : MyClass { }

それからあなたはすることができます

MyClass2 myClass2 = confused.GetMyClass<MyClass2>();

他の関数ではそれを行うことはできません。

于 2011-07-14T14:29:02.040 に答える
1

MyClass基本クラス (またはインターフェイスIMyClass) である可能性があります。制約付きのジェネリック バージョンでは、この関数を、共通のベースまたはインターフェイスから派生した (または実装した) 任意のクラスに対して機能させ、ベースとしてではなく、その派生クラスとして結果を返すようにします。

class MyClass { }
class MySpecializedClass : MyClass { } 
// etc.
于 2011-07-14T14:28:08.873 に答える
1

非常に大きな違いがあります
。非ジェネリック バージョンは type のインスタンスのみを返すことができますがMyClass、ジェネリック バージョンは type のインスタンスと!MyClassから派生したすべてのクラスを返すことができます。MyClass

于 2011-07-14T14:28:39.720 に答える
0

それらは同じではありません。ジェネリックを使用すると、継承されたクラスを次のように構築できます。

class MyClass
{
    public override string ToString()
    {
        return "I am confused now";
    }
}

class InheritedClass : MyClass
{
}

class Confused
{
    public MyClass GetMyClass()
    {
        return new MyClass();
    }

    public T GetMyClass<T>() where T : MyClass, new()
    {
        return System.Activator.CreateInstance<T>();
    }
}

class Program
{
    static void Main()
    {
        Confused c = new Confused();
        System.Console.WriteLine(c.GetMyClass());
        System.Console.WriteLine(c.GetMyClass<MyClass>());
        System.Console.WriteLine(c.GetMyClass<InheritedClass>());
    }
}
于 2011-07-14T14:38:06.083 に答える
0

を呼び出した場合にのみ、同じ結果が得られます.GetMyClass<MyClass>()。ただし、他のクラスを作成できるようにするために、追加のメソッドが作成されていると思いますか? そうでない場合、それらは同じであるため、冗長です(アセンブリ内にオーバーヘッドがあるため、汎用バージョンを削除します)。

それらは異なって使用されていますか?

于 2011-07-14T14:30:08.803 に答える
0

いいえ、それらは同じではありません。1 つ目はオブジェクトのみを構築し、2 つ目はtype パラメータに基づいて 、または の子孫でMyClassある任意のオブジェクトを構築します。MyClassMyClass

于 2011-07-14T14:28:40.937 に答える
-1

よくわかりませんが、Generics は .NET のランタイム機能です。したがって、非ジェネリック メソッドは、同等に使用されていても、ジェネリック メソッドと同等ではありません。それらは公開されているため、これを最適化して取り除くことはできません。

于 2011-07-14T14:28:45.403 に答える