C# Generics и общие ограничения
Я пишу общий абстрактный класс A с параметром типа T, который я намерен получить с классом B.
A имеет член данных mX, экземпляр класса C, с универсальной функцией. Эта универсальная функция GetAllOfType() имеет один параметр типа T. Этот параметр типа ограничен третьим классом D. GetAllOfType() выполняет поиск в контейнере экземпляров D, который включает в себя экземпляры производных классов D, и возвращает подмножество типа T (отсюда и ограничение на D).
Сам класс D не имеет конкретного члена данных, int mY, но некоторые производные классы D, такие как E и F., имеют его.
public class D
{
}
public class E : D
{
public int mY;
}
public class F : D
{
public int mY;
}
public class C
{
public T[] GetAllOfType<T>() where T : D
{ ... }
}
public class A<T>
{
private C mX;
...
}
public class B : A<E>
{
...
}
Итак, вот где начинается моя проблема:
Тип параметра, который класс B использует для наследования и реализации класса A, является производным классом D. Я пытаюсь написать функцию Foo в классе A, которая перечисляет через GetAllOfType() и обращается к члену mY типа E, F или любому другому член, который имеет мой.
public class A<T>
{
private C mX;
protected Foo()
{
foreach (var c in mX.GetAllOfType<T>())
{
c.mY = 0;
}
}
}
public class B : A<E>
{
public Bar()
{
Foo();
}
}
Проблема, однако, заключается в том, что GetAllOfType() ограничен, и я получаю ошибку за то, что не ограничиваю класс A.
Я попытался ограничить A как таковой:
public class A<T> where T : D
Но я получаю ошибку во время компиляции в соответствии с:
Тип
T' does not contain a definition for
MY'и без метода расширенияmY' of type
T'может быть найдено (вам не хватает директивы using или ссылки на сборку?)
Я также пытался ограничиться несколькими производными классами:
public class A<T> where T : E, F
Но я также получаю сообщение об ошибке:
Ограничение типа класса 'F' должно быть указано перед любыми другими ограничениями. Рассмотрите возможность перемещения ограничения типа в начало списка ограничений.
Я попытался переключить их:
public class A<T> where T : F, E
Аналогично, результат - та же самая ошибка, но с F, переключенным на E.
Возможно ли то, что я пытаюсь сделать? Что я делаю неправильно?
Опять же, я не могу ничего изменить в классах C, D, E и F.
1 ответ
При добавлении ограничения на общий параметр A,
public class A<T> where T : D
причина, по которой вы получаете вторую ошибку, Type T' does not contain a definition for mY' and no extension method mY' of typeT' could be found (are you missing a using directive or an assembly reference?)
неудивительно, потому что D не имеет mY, только производные классы E и F. Причина
public class A<T> where T : E, F
не работает, потому что вы можете указать только одно ограничение типа базового класса (C# не имеет множественного наследования). Любые дальнейшие ограничения должны быть интерфейсами или такими вещами, как class
или же new()
Если вы действительно не можете ничего изменить в этих классах, то, что вы пытаетесь выполнить, может быть неоправданно сложно, насколько я могу судить. Я могу придумать несколько уродливых способов (рефлексия или много кастинга), но это не может быть правильным путем. Может быть, что-то умное, что я скучаю. Было бы здорово, если бы вы могли представить интерфейс (или промежуточный класс) со свойством mY и иметь наследование E и F от этого. Тогда вы могли бы ограничить T к этому вместо D
и все было бы хорошо. Иначе я не вижу способа узнать, что это за D
вы имеете дело, кроме как во время выполнения.