无法将派生类型隐式转换为其基类泛型类型

Mis*_*pic 26 .net c# generics

我有以下类和接口:

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; }
}
Run Code Online (Sandbox Code Playgroud)

现在,我有一个工厂将返回从ThingConsumer派生的对象,如:

public class MyThingConsumer : ThingConsumer<Thing>
{
}
Run Code Online (Sandbox Code Playgroud)

我的工厂目前看起来像这样:

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

我被这个错误搞砸了: Error 1 Cannot implicitly convert type 'ConsoleApplication1.MyThingConsumer' to 'ConsoleApplication1.ThingConsumer<T>'

谁知道如何完成我在这里尝试的东西?

谢谢!

克里斯

McG*_*gle 10

如果您创建ThingConsumer<T>一个接口而不是一个抽象类,那么您的代码将按原样运行.

public interface IThingConsumer<T> where T : IThing
{
    string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

编辑

还需要一个改变.在ThingConsumerFactory,返回到返回类型IThingConsumer<T>:

return (IThingConsumer<T>)new MyThingConsumer();
Run Code Online (Sandbox Code Playgroud)

  • 为了满足好奇心,为什么要禁止使用抽象类?我一直认为抽象和接口基本上是契约,为什么一个在这种情况下是有效的而不是另一个? (2认同)
  • @ChrisHardie我问了一个与此相关的问题,并得到了一个很好的答案,为什么可以转换为接口而不是抽象类:http://stackoverflow.com/a/12335905/1001985 (2认同)

Mat*_*dge 5

即使and 和,编译器也会在从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);
Run Code Online (Sandbox Code Playgroud)