Каков тип параметра для универсального параметра функции при вызове из базового класса с помощью this.
Запутанный вопрос, я знаю. Учитывая следующее:
class Test
{
public static void GenericFunc<T>(T SomeType)
{
System.Console.WriteLine("typeof(T): " + typeof(T).Name);
System.Console.WriteLine("SomeType.GetType(): " + SomeType.GetType().Name);
}
}
public class BaseType
{
public void RunTest() { Test.GenericFunc(this); }
}
public class DerivedType : BaseType { }
Следующий код производит интересный вывод:
DerivedType Derived = new DerivedType();
Derived.RunTest();
// output:
// typeof(T): BaseType
// SomeType.GetType(): DerivedType
Тем не менее, это ведет себя так, как я ожидал:
Test.GenericFunc(new Derived());
// output:
// typeof(T): DerivedType
// SomeType.GetType(): DerivedType
Может кто-нибудь помочь мне понять механизм здесь, который заставляет T быть оцененным как BaseType в первом случае?
Заранее спасибо!
2 ответа
Потому что это:
public class BaseType
{
public void RunTest() { Test.GenericFunc(this); }
}
В основном эквивалентно:
public class BaseType
{
public void RunTest() { Test.GenericFunc<BaseType>(this); }
}
Следовательно GenericFunc
устанавливается во время компиляции с T = BaseType
, Тем не менее this
объект, который вы передаете во время выполнения, является производным типом, который вы получаете SomeType.GetType()
,
Во втором случае компилятор выводит тип как DerivedType
непосредственно от использования и, следовательно, GenericFunc
завязывается с T = DerivedType
,
Если не задействован "динамический" тип, разрешение перегрузки и определение типа выполняются во время компиляции, а не во время выполнения.
Когда разрешение перегрузки видит Test.GenericFunc(this);
он должен вывести аргумент универсального типа, соответствующий отсутствующему параметру универсального типа. Это простая проблема; он использует тип времени компиляции this
и внутри метод BaseType
, явно тип времени компиляции this
всегда BaseType
,
Поэтому разрешение перегрузки предполагает, что вы намеревались вызвать Test.GenericFunc<BaseType>(this)
,
Если вы хотите, чтобы это было решено во время выполнения, вы можете сделать это в C# 4. Просто скажите Test.GenericFunc((dynamic)this)
, Это снова запустит механизм разрешения перегрузки во время выполнения, после чего будет притворяться, что вы произвели this
к его типу выполнения обратно во время компиляции.
Да, это так же дорого, как кажется. Если вам нужен семантический анализ во время выполнения, нам нужно запустить семантический анализатор во время выполнения.