наследование с помощью c # generic, а тип класса наследуется - PullRequest
3 голосов
/ 21 февраля 2012

что-то подобное возможно в C #?

Предположим, у меня есть это:

public class T : U
{
 ...
}

и я хочу это:

public class A<T> : B<U>
{
...
}

чтобы я мог иметь это в своем коде:

B<U> x = new A<T>();

Ответы [ 3 ]

2 голосов
/ 21 февраля 2012

Вы не можете получить его в точности так, как пишете, но вы можете сделать это:

public class A<T, U> : B<U> where T : U
{
   ...
}

, а затем сделать

B<U> x = new A<T, U>();
1 голос
/ 21 февраля 2012

Этот исходный код работает нормально ... Хотя, возможно, есть некоторая путаница из-за используемых вами терминов ...

Я считаю, что написанный вами код можно переписать более четко следующим образом:

void Main()
{
    B<Foobar> x = new A<Wibble>();

}

// Define other methods and classes here
public class Foobar
{
}

public class Wibble : Foobar
{
}

public class B<U>
{
}

public class A<T> : B<Foobar>
{
}

Ключевым моментом, на который следует обратить внимание, является то, что иногда вы использовали U в контексте универсального параметра, а иногда вы использовали его в качестве конкретного класса.

Приведенный выше код эквивалентен (в терминах IL, к которому LINQPad его компилирует):

void Main()
{
    B<U> x = new A<T>();

}

// Define other methods and classes here
public class U
{
}

public class T : U
{
}

public class B<U>
{
}

public class A<T> : B<U>
{
}

Только два последних класса используют универсальные параметры, и последний класс не имеет U, определенный как универсальный параметр, поэтому он обрабатывает его какконкретный класс.Трудно сказать, хотите ли вы этого или нет, потому что вы не сказали нам, чего хотите, просто показали нам некоторый код.Я думаю, что, вероятно, вам нужно решение с двумя общими параметрами, на которое ответил @Roy Dictus, но вы можете захотеть этого.Сложно сказать.; -)

Следует отметить, что я частично зачисляю этот ответ на предыдущий удаленный ответ.Этот ответ указал на то, что код прекрасно компилируется, что вдохновило меня на тестирование реального кода.К сожалению, с удаленным ответом я не могу отдать должное этому человеку за вдохновение.

Спасибо всем.Крис, это решает мою проблему при условии, что я могу вызвать конструктор T в конструкторе A<T> ниже: открытый класс A<T>: B<Foobar> {} Как я могу это сделать?- jambodev 1 мин. Назад

В этом случае T является универсальным параметром, поэтому вы должны сообщить компилятору, что T определенно конструируем.Для этого вам нужно ограничить T, чтобы убедиться, что у него есть конструктор.Тогда вы сможете создавать новые его экземпляры в любое время (например, T foo = new T();

. Конечно, вы не можете вызвать конструктор так же, как вы бы связали конструктор базового класса, так как A не выводитиз T любым способом, он просто использует объекты типа T в своих общих шаблонах.

public class A<T> : B<Foobar> where T :new()
{
    public T MyInstance {get; set;}
    public A()
    {
        MyInstance = new T();
    }
}

void Main()
{
    B<Foobar> x = new A<Wibble>();
    Wibble y = ((A<Wibble>)x).MyInstance;
}

(этот код заменяет эквивалентные методы из моего первого блока кода)

Обратите внимание, что yобъект типа Wibble, который был создан в обработчике x. Обратите внимание также, что мне нужно было привести x перед тем, как получить к нему доступ, потому что B<Foobar> ничего не знает об использовании универсального типа Wibble.

0 голосов
/ 21 февраля 2012

Не совсем понятно, что вы должны делать (имена классов не помогают, мой мозг боролся с классом T).Ответ Роя Диктуса - то, что вы хотите, или, возможно, ответ Криса был тем, что вы ищете?Я интерпретировал вопрос иначе, чем любой из первых, например:

    public class MyBaseClass  {}

    public class MyClass : MyBaseClass {}

    interface IB<out T>{}

    public class B<T> : IB<T> { }

    public class A<T> : B<T>   {}

    static void Main(string[] args)
    {
        IB<MyBaseClass> myVar = new A<MyClass>();
    }

Ключ в том, что интерфейсы поддерживают ковариацию, классы не .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...