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 forMY'и без метода расширения mY' of typeT'может быть найдено (вам не хватает директивы 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 вы имеете дело, кроме как во время выполнения.

Другие вопросы по тегам