3

だから私たちはこれを持っています:

public interface IWidget
{
    int Id { get; set; }
}

public class Widget : IWidget
{
    public int Id { get; set; }
}

public class WidgetProcessor
{
    public static void ProcessWidgets1(IList<IWidget> widgets)
    { }

    public static void ProcessWidgets2<T>(IList<T> widgets) where T : IWidget
    { }
}

これがコンパイルされない理由が WidgetProcessor.ProcessWidgets1(new List<Widget>()); わかりました。共分散に関する C# の規則では、そうすべきではないと賢明に述べられています。

しかし、ProcessWidgets2: 何が...? これが
どのようにコンパイルおよび実行されるのですか: WidgetProcessor.ProcessWidgets2(new List<Widget>());

私の無知が取り除かれることを楽しみにしていますが、ProcessWidgets1 と ProcessWidgets2 が (事実上) どのように違うのかわかりません。

4

2 に答える 2

5

ProcessWidgets2<T>ジェネリックメソッドです。でそれを呼び出すとnew List<Widget>()、コンパイラは型TWidgetであると推測し、これは制約に一致し、それを呼び出しList<T>ますIList<T>

複数の呼び出しに分割されているかのように見るのが最も簡単な可能性があります。

IList<Widget> temp = new List<Widget>();
WidgetProcessor.ProcessWidgets2<Widget>(temp); // Widget is an IWidget, so this matches constraints

List<T>を直接実装し、コンパイラによって推論された特定の型IList<T>で呼び出しているため、ここでの違いはありません。

于 2013-03-21T15:55:31.217 に答える
0

最初の例では、次のコードを実行できます。

widgets.Add(new SomeOtherWidget());

widgetsが実際に であることが許可されている場合は、オブジェクトのリストにList<Widget>a を入れることになります。オブジェクトを取り出したとき、それはまったくない可能性があるため、それは悪いことです。SomeOtherWidgetWidgetWidget

2 番目の例でwidgets.Add(new SomeOtherWidget());は、コンパイルされません。 SomeOtherWidgetタイプにはなりませんT。古いオブジェクトではなく、Addtype のオブジェクトを使用してリストを呼び出すことのみが許可されるため、型の安全性を維持できます。TIWidget

于 2013-03-21T16:11:29.347 に答える