Этот исходный код работает нормально ... Хотя, возможно, есть некоторая путаница из-за используемых вами терминов ...
Я считаю, что написанный вами код можно переписать более четко следующим образом:
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
.