Интерфейс с generic аргументом, полиморфизм
Подскажите пожалуйста, что делаю не так. Нужно в один словарь поместить различные объекты реализующие один интерфейс с generic аргументом.
Вот код для примера:
Есть интерфейс параметра и две реализации OneParameter и TwoParameter:
public interface IParameter
{
string Name { get; }
}
public class ParameterBase : IParameter
{
public ParameterBase(string name)
{
Name = name;
}
public string Name { get; }
}
public class OneParameter : ParameterBase
{
public OneParameter(int oneProperty)
: base("One")
{
OneProperty = oneProperty;
}
public int OneProperty { get; set; }
}
public class TwoParameter : ParameterBase
{
public TwoParameter(int twoProperty)
: base("Two")
{
TwoProperty = twoProperty;
}
public int TwoProperty { get; set; }
}
Также есть две стратегии поведения:
public interface IRequestStrategy<TRequestParameter>
where TRequestParameter : IParameter
{
Task RequestDocument(TRequestParameter parameter);
}
public class OneRequestStrategy : IRequestStrategy<OneParameter>
{
public Task RequestDocument(OneParameter parameter)
{
throw new NotImplementedException();
}
}
public class TwoRequestStrategy : IRequestStrategy<TwoParameter>
{
public Task RequestDocument(TwoParameter parameter)
{
throw new NotImplementedException();
}
}
Далее пытаюсь зарегистрирровать стратегии в одном словаре:
private static void TestStrategies()
{
Dictionary<int, IRequestStrategy<IParameter>> _strategies =
new Dictionary<int, IRequestStrategy<IParameter>>();
var str1 = new OneRequestStrategy();
var str2 = new TwoRequestStrategy();
_strategies.Add(1, (IRequestStrategy<IParameter>)str1);
_strategies.Add(2, str2);
}
При этом в первом случае ошибка приведения типов:
Unable to cast object of type 'OneRequestStrategy' to type IRequestStrategy`1[IParameter]'.
Ну и во втором тоже самое только при компиляции:
Error CS1503 : cannot convert from 'TwoRequestStrategy' to 'IRequestStrategy<IParameter>'
Ответы (1 шт):
Автор решения: Dmitri Nesteruk
→ Ссылка
Предлагаю использовать маркер интерфейс:
public interface IRequestStrategy{}
Добавляем его в наследники:
public interface IRequestStrategy<TRequestParameter>
: IRequestStrategy
where TRequestParameter : IParameter
Потом в словаре храним вот так:
Dictionary<int, IRequestStrategy> _strategies =
new Dictionary<int, IRequestStrategy>();
А при доставании из словаря нужно будет проверять типы или использовать паттерн Visitor.