Я прочитал все о Covariance, Contravariance и Invariance, но я все еще не понимаю, как разработать свой код
Я искал и читал / изучал столько, сколько казалось разумным до публикации этого. Я нашел похожие вопросы, но большинство постов на самом деле больше связаны с передачей "Списка производных типов" вызовам функций, которые требуют "Список базового типа". Я могу оценить примеры животных и чувствую, что у меня есть намного лучшее понимание после моих исследований.
При этом, я все еще не могу понять, как решить в моем конкретном случае использования. У меня есть необходимость агрегировать экземпляры "GenericClass of TestInterface(s)" в коллекции. Я скопировал / вставил ниже всех моих возможностей в том, что может показаться лучшим способом для выполнения задач.
namespace Covariance
{
class Program
{
protected static ISet<GenericClass<TestInterface>> set = new HashSet<GenericClass<TestInterface>>();
static void Main(string[] args)
{
set.Add(new GenericClass<A>());
set.Add(new GenericClass<B>());
}
}
class GenericClass<TemplateClass> where TemplateClass : TestInterface
{
TemplateClass goo;
}
public interface TestInterface
{
void test();
}
public class A : TestInterface
{
public void test()
{
}
}
class B : A
{
}
}
Приведенный выше код завершается ошибкой со следующими ошибками компиляции:
ошибка CS1503: аргумент 1: невозможно преобразовать из Covariance.GenericClass в Covariance.GenericClass
ошибка CS1503: аргумент 1: невозможно преобразовать из Covariance.GenericClass в Covariance.GenericClass
Любая помощь / руководство или соответствующие ссылки будут высоко ценится. Еще раз извиняюсь, если это дублирующий вопрос. Благодарю вас!
1 ответ
Вы можете объявлять модификаторы дисперсии (in, out) только для универсальных интерфейсов, но не для типов. Поэтому одним из способов решения этой проблемы было бы объявить интерфейс для вашего GenericClass
, как это:
interface IGenericClass<out TemplateClass> where TemplateClass : TestInterface {
TemplateClass goo { get; }
}
class GenericClass<TemplateClass> : IGenericClass<TemplateClass> where TemplateClass : TestInterface
{
public TemplateClass goo { get; }
}
А потом
class Program {
protected static ISet<IGenericClass<TestInterface>> set = new HashSet<IGenericClass<TestInterface>>();
static void Main(string[] args) {
set.Add(new GenericClass<A>());
set.Add(new GenericClass<B>());
}
}