5

次のセットアップがあり、オブジェクトをジェネリック型に変換できないようです。実際には基本クラスですが。なぜこれが機能しないのですか?私にはとても論理的に思えます。

public class AList<T> where T : A
{
    void DoStuff(T foo)
    {
    }

    void CallDoStuff()
    {
        DoStuff(new A()); // ERROR: Cannot convert A to T
    }
}

public class A
{
}
4

5 に答える 5

3

ここでの問題は、それがまたは から派生したクラスTでなければならないという制約があることです。 さて、具象型でインスタンス化すると、非常に特殊なクラスになります。また、それ自体ではなく、そのサブクラスでインスタンス化した場合、は のサブクラスです。A A
AListTAListATA

サブクラスによって追加されるすべての情報が失われるため、基本クラスの実行時型を持つインスタンスをそのサブクラスの 1 つに変換することはできません。

例:

public class Animal
{
    public int Foo { get; set; }
}

public class Cat : Animal
{
    public int Bar { get; set; }
}

Derived d = new Base();

そのコードが機能すると思いますか? Cataも aですAnimalが、 aは a ではないため、そうでAnimalはありませんCat
上記のコードが実際に機能することを期待する場合は、次のコードを実行するとどうなるかを自問してください:d.Bar = 42;
Animalには の定義が含まれていませんBar

あなたのコードでも同じことが起こっています - ゲーム内のジェネリクスで少しだけわかりにくくなっています。

于 2013-02-18T11:16:04.277 に答える
2

Tから派生するクラスでもある可能性があるため、のインスタンスを type のパラメーターとしてA配置することはできません。メソッドを呼び出すようなもので、with と type の引数を取ります。ATintobject

于 2013-02-18T11:15:13.173 に答える
1

これは、 が暗黙的objectに変換できないのと同じ理由です。int

メソッドは子クラスを想定しており、親を渡すため、明示的なキャストが必要です。

于 2013-02-18T11:14:06.477 に答える
0

T に A を拡張するように求めているためです。したがって、T を A に置き換えることはできますが、A を T に置き換えることはできません。

Cat : Animal の場合、いつでも Animal を Cat に変換できるというわけではありません。

于 2013-02-18T11:15:29.670 に答える
0

制約が原因であることがわかっているため、 fromActivatorのインスタンスを提供するために使用してみてください。ATTAnew A()TT

T obj = Activator.CreateInstance<T>();
DoStuff(obj);

または、他の回答が述べたようにあなたのキャストを行いますobjectが、これはすべての場合に機能するとは限りません。

T obj = (T)new A();
DoStuff(obj);
于 2013-02-18T11:18:12.693 に答える