4

以下の「DoTest1」メソッドを呼び出すことが問題である理由について、誰かが光を当てることができますか?

T が GridCore から派生することを my where T : GridCore で指定しているにもかかわらず、着信 GridCore オブジェクトをジェネリック型 T にキャストする必要があるのはなぜですか?

ありがとう

public partial class Form1 : Form
{
    private void button1_Click(object sender, EventArgs e)
    {
        MyTest<MyAlbum> mytest = new MyTest<MyAlbum>();
        mytest.DoTest1(new MyAlbum());
        mytest.DoTest2(new MyAlbum());
    }
}

public class GridCore { }

public class MyAlbum : GridCore
{
    public string Title { get; set; }
}

public class MyTest<T> where T : GridCore
{
    private List<T> _list = new List<T>();

    public void DoTest1(GridCore ma)
    {
        //_list.Add(ma);        <-- why doesn't this work?
        _list.Add((T)ma);
    }

    public void DoTest2(T ma)
    {
        _list.Add(ma);
    }

}
4

5 に答える 5

2

メソッドがそれを推測することを期待している場合GridCoreT制約のため)、コンパイル時にそれはできません。そのため、エラーが発生しています。

ジェネリック メソッド (C# プログラミング ガイド)

コンパイラは、渡されたメソッド引数に基づいて型パラメーターを推測できます。制約または戻り値からのみ型パラメーターを推測することはできません

于 2013-03-28T08:59:53.853 に答える
0

where T: GridCoreは、 aTが であるGridCoreことを意味します。GridCoreつまり、 の基本型またはインターフェイスですT

しかし、あなたのリストは ですList<T>。つまり、それは のリストでTあり、Tおそらく の派生クラスですGridCore

がフィールドを持っていると仮定して、フィールドを持っていると仮定Tしましょう。DerivedGridCoreint XGridCoreint X

型を明示的に変換しない限り (または暗黙的な演算子がある場合)、コンパイラはその変換が保証されていないため、その仮定を行いません。

より直感的に考えると、aGirafeは ですがAnimalAnimal必ずしも a である必要はありませんGirafe。aTirgetはいずれかAnimalです。

于 2013-03-28T09:09:37.000 に答える
0
       private List<T> _list = new List<T>(); 

_list はタイプ T ですが、ma は

       public void DoTest1(GridCore ma)

タイプは GridCore です。それがうまくいかない理由です。

于 2013-03-28T08:57:36.073 に答える
0

C# では、開発者がオブジェクトをその派生型のいずれかに明示的にキャストする必要があります。そのようなキャストは実行時に失敗する可能性があるためです。T は GridCore から派生しています。だからあなたは書くことができます

GridCore gridcore = new T();

ただし、明示的にキャストする必要があります

T t = (T)new GridCore();
于 2013-03-28T08:58:24.387 に答える
0

要するに、すべてGridCoreの がであるとは限らないからTです。すべてTの はGridCores(制約のため) であり、その逆ではありません。

これを想像してください:

public class MyChicken : GridCore
{
    public string FavouriteColour { get; set; }
}

....

new MyTest<MyAlbum>().DoTest1(new MyChicken());

コードが許可されていれば、アルバムを期待するときにニワトリができます。言うまでもなく、音楽を聴こうとしている人は、期待どおりの結果を得られない可能性があります。

おそらくあなたが望むのは、クラスが扱うものDoTest1だけを受け入れるように署名を変更することです:T

public void DoTest1(T ma)

これで、 aはそのメソッドへのMyTest<MyAlbum>のみを受け入れます。MyAlbumDoTest1

于 2013-03-28T09:12:15.053 に答える