Я считаю, что Бен Вейгт дал вам ответ в своем комментарии.
Вы могли бы достичь результата вы ожидаете, указав тип, который декларирует скрытие (new
) метод реализации в качестве общего ограничения:
class Test<T> where T : SomeObject, new()
{
public Test()
{
T t = new T();
object t1 = t;
Console.WriteLine(t.ToString());
Console.WriteLine(t1.ToString());
}
}
Этот выход:
Hello world.
Program.SomeObject
Редактировать: Компилятор разрешает любые вызовы членов для общих типов в отношении общих ограничений. Это подразумевается в Руководстве # Программирование MSDN C на Constraints on Type Parameters:
Ограничивая параметр типа, вы увеличиваете число допустимых операций и вызовы методов тех, которые поддерживаются типа ограничивающего и всех типов в иерархии наследования. Поэтому, когда вы разрабатываете общие классы или методы, если вы выполняете какую-либо операцию над общими членами, помимо простого назначения или вызываете любые методы, не поддерживаемые System.Object, вам придется применять ограничения к параметру типа.
Чтобы прояснить ситуацию: представьте, что вы определили новый метод, Foo
в своем классе:
class SomeObject
{
public SomeObject() { }
public void Foo() { }
}
Попытка вызвать Foo
приведет к ошибке времени компиляции. Единственное, что компилятор знает о родовом типе T
, состоит в том, что он имеет безпараметрический конструктор - он не знает каких-либо методов, которые он мог бы определить.
class Test<T> where T : new()
{
public Test()
{
T t = new T();
t.Foo(); // Error: 'T' does not contain a definition for 'Foo'
// and no extension method 'Foo' accepting a
// first argument of type 'T' could be found
}
}
Однако, если ограничить T
быть типа SomeObject
, то компилятор будет знать, искать определения Foo
в SomeObject
класса:
class Test<T> where T : SomeObject, new()
{
public Test()
{
T t = new T();
t.Foo(); // SomeObject.Foo gets called
}
}
Аргументация очень похож на скрытый члены.
Нет, дженерики рано переплете. Разрешение перегрузки использует общие ограничения, но не фактический тип. –