Невозможно неявно преобразовать производный тип в его базовый общий тип
У меня есть следующие классы и интерфейсы:
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; }
}
Теперь у меня есть factory, который вернет объекты, полученные из ThingConsumer, например:
public class MyThingConsumer : ThingConsumer<Thing>
{
}
Теперь мой factory выглядит следующим образом:
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>'
Кто-нибудь знает, как выполнить то, что я пытаюсь здесь?
Спасибо!
Крис
Ответы
Ответ 1
Если вы создаете ThingConsumer<T>
интерфейс, а не абстрактный класс, тогда ваш код будет работать как есть.
public interface IThingConsumer<T> where T : IThing
{
string Name { get; set; }
}
Изменить
Необходимо еще одно изменение. В ThingConsumerFactory
верните тип возврата IThingConsumer<T>
:
return (IThingConsumer<T>)new MyThingConsumer();
Ответ 2
Компилятор обходит конверсию с MyThingConsumer
до ThingConsumer<T>
, хотя T:IThing
и MyThingConsumer:Thingconsumer<Thing>
и Thing:IThing
. Это довольно много обручей, чтобы проскочить!
Код работает, если вы используете return new MyThingConsumer() as ThingConsumer<T>;
вместо прямого трансляции. Вы знаете, что результат никогда не будет null
, и компилятор счастлив, потому что во время выполнения гарантируется возвращаемое значение правильного типа.
Edit:
Вот полный код, который я использовал для тестирования (в 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);
Ответ 3
Вам нужно определить свой класс, как я полагаю:
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>();