29

次のクラスとインターフェイスがあります。

public interface IThing
{
    string Name { get; }
}

public class Thing : IThing
{
    public string Name { get; set; }
}

public abstract class ThingConsumer<T> where T : IThing
{
    public string Name { get; set; }
}

これで、次のような ThingConsumer から派生したオブジェクトを返すファクトリができました。

public class MyThingConsumer : ThingConsumer<Thing>
{
}

私の工場は現在、次のようになっています。

public static class ThingConsumerFactory<T> where T : IThing
{
    public static ThingConsumer<T> GetThingConsumer(){
        if (typeof(T) == typeof(Thing))
        {
            return new MyThingConsumer();
        }
        else
        {
            return null;
        }
    }
}

私はこのエラーでつまずいています:Error 1 Cannot implicitly convert type 'ConsoleApplication1.MyThingConsumer' to 'ConsoleApplication1.ThingConsumer<T>'

私がここで試みていることを達成する方法を知っている人はいますか?

ありがとう!

クリス

4

3 に答える 3

11

ThingConsumer<T>抽象クラスではなくインターフェイスを作成すると、コードはそのまま機能します。

public interface IThingConsumer<T> where T : IThing
{
    string Name { get; set; }
}

編集

もう 1 つの変更が必要です。ではThingConsumerFactory、戻り値の型にキャスト バックしIThingConsumer<T>ます。

return (IThingConsumer<T>)new MyThingConsumer();
于 2012-09-07T19:29:54.410 に答える
5

MyThingConsumerコンパイラは、 からへの変換でつまずきThingConsumer<T>ますがT:IThingMyThingConsumer:Thingconsumer<Thing>およびThing:IThingです。これは、ジャンプするのにかなりの数のフープです!

return new MyThingConsumer() as ThingConsumer<T>;直接キャストの代わりに使用すると、コードが機能します。null実行時に正しい型の戻り値が保証されるため、結果が決して にならないことがわかり、コンパイラは満足しています。

編集: これは私がテストに使用した完全なコードです(Snippyで):

public interface IThing
{
    string Name { get; }
}

public class Thing : IThing
{
    public string Name { get; set; }
}

public abstract class ThingConsumer<T> where T : IThing
{
    public string Name { get; set; }
}

public class MyThingConsumer : ThingConsumer<Thing>
{
}

public static class ThingConsumerFactory<T> where T : IThing
{
    public static ThingConsumer<T> GetThingConsumer()
    {
        if (typeof(T) == typeof(Thing))
        {
            return new MyThingConsumer() as ThingConsumer<T>;
        }
        else
        {
            return null;
        }
    }
}

...

var thing = ThingConsumerFactory<Thing>.GetThingConsumer();
Console.WriteLine(thing);
于 2012-09-07T20:06:17.633 に答える
1

次のようにクラスを定義する必要があります。

public class MyThingConsumer<Thing> : ThingConsumer

その理由は、ThingConsumerこれで定義にすでに入力されているためです。where T : IThing

これで、電話をかけることができますreturn new MyThingConsumer<T>();

これは、期待される戻り値の型と一致する必要がありますThingConsumer<T>

編集

混乱して申し訳ありませんが、これがうまくいくはずです:

public class MyThingConsumer<T> : ThingConsumer<T> where T : IThing

return new MyThingConsumer<T>();
于 2012-09-07T19:12:41.887 に答える