Ошибка при преобразовании конкретного класса к обобщенному интерфейсу
У меня есть модели:
public class ModelA
{
public int Id {get;set;}
}
public class ModelB : ModelA
{
public string Name {get;set;}
}
public class ModelC
{
public string Result {get;set;}
}
Обобщенный интерфейс:
public interface ISample<T, TResult> where T : ModelA where TResult : ModelC
{
Task<IEnumerable<TResult>> Do(IEnumerable<T> models);
}
Реализация:
public class Sample: ISample<ModelB, ModelC>
{
Task<IEnumerable<ModelC>> Do(IEnumerable<ModelB> models) {//Do..}
}
И некая фабрика:
public static class SampleFactory
{
private readonly static Dictionary<Type, ISample<ModelA, ModelC>> samples = InitDictionary();
public static ISample<ModelA, ModelC> Get(Type sampleType)
{
return samples[sampleType];
}
private static Dictionary<Type, ISample<ModelA, ModelC>> InitDictionary()
{
return new()
{
samples[typeof(Sample)] = (ISample<ModelA, ModelC>)new Sample();
}
}
}
Проблема: компилируется без каких либо ошибок, но в рантайме, при запросе объекта из фабрики выкидывает исключение: невозможно преобразовать из Sample в ISample<ModelA, ModelC>. Подскажите в чем здесь проблема?
Ответы (1 шт):
Невозможно преобразовать из Sample в ISample<ModelA, ModelC> потому что он ISample<ModelB, ModelC>. Апкаст на дженериках не работает, он работает только на основных типах. То есть то что вы хотите, в чистом виде работать не может.
Самое очевидное решение здесь - это Dictionary<Type, object>. Но ваш пример сильно обфусцирован до такой степени, что я вообще не вижу смысла в словаре внутри фабрики, так как он согласно этому коду может иметь только один ключ, смысловая часть всей задумки потеряна при обфускации.