Общая проблема - C # 3.0 - PullRequest
0 голосов
/ 09 мая 2011

У меня проблема:

class Base
{
}

class DerivedClass : Base
{
}

class Test<T> where T : Base
{
}

и как-то так:

Test<Base> a = new Test<DerivedClass>();

Я думаю, что есть способ обойти это в C # 4.0, но есть ли способ сделать что-то подобное в C # 3?

Ответы [ 2 ]

3 голосов
/ 09 мая 2011

Краткий ответ: нет, нет пути.
Длинный ответ: Нет, ни в C # 3.0, ни в C # 4.0 нет никакого способа, потому что совместная и контравариантность вообще не поддерживается в C # 3.0 и только для типов делегатов и интерфейсов в C # 4.0.

UPDATE:
Если вы хотите сохранить несколько экземпляров этого класса в списке, независимо от конкретного типа T, один обходной путь может выглядеть следующим образом:
Создайте интерфейс ITest, который использует Base везде, где вы будете использовать T. Заставьте Test<T> реализовать этот интерфейс и скрыть методы от ITest, используя явную реализацию интерфейса. Используйте ITest в качестве типа параметра для вашего метода. Пример кода:

class Base
{
    public int Info { get; set; }
}

class Derived : Base
{
    public int Info2 { get; set; }
}

interface ITest
{
    Base Data { get; set; }
}

class Test<T> : ITest
    where T : Base
{
    public T Data { get { return (T) (((ITest) this).Data); } set { ((ITest) this).Data = value; } }

    Base ITest.Data { get; set; }
}

List<ITest> list = new List<ITest>();
list.Add(new Test<Base>());
list.Add(new Test<Derived>());

Если вы просто хотите передать этот класс методу, не требуя конкретного T, вы также можете сделать свой метод универсальным:

void YourMethod<T>(Test<T> test) where T : Base
{
    Console.WriteLine(test.Data.Info);
}

YourMethod(new Test<Base>());
YourMethod(new Test<Derived>());
0 голосов
/ 09 мая 2011

Это ковариация, которую вы хотите, и в C # 3.0 нет особого пути, кроме использования приведения.

A Test<DerivedClass> не наследуется от Test<Base>, даже если DerivedClass наследуется от Base.

...