Как работает вывод универсального типа в C #? - PullRequest
3 голосов
/ 03 февраля 2011

Если у меня следующий код

private BaseMessage getMessage()
{
    return new OtherMessage();
}

private void CheckType<T>(T type)
{
    Console.WriteLine(type.GetType().ToString());
    Console.WriteLine(typeof(T).ToString());
}

private void DoChecks()
{
     BaseMessage mess = getMessage();
     CheckType(mess);
}

, почему мне выводятся разные типы?Есть ли способ заставить вывод типа использовать фактический тип передаваемого объекта?

Ответы [ 2 ]

6 голосов
/ 03 февраля 2011

Вывод общего типа означает, что компилятор автоматически разрешает типы передаваемых аргументов без необходимости явного указания типа передаваемого вами типа.Это означает, что это делается во время компиляции: в вашем коде во время компиляции компилятор знает только о BaseMessage, поэтому параметр будет передан как BaseMessage.Во время выполнения фактическим типом параметра будет OtherMessage, но это не имеет значения для компилятора.

Следовательно, вывод, который вы получаете, абсолютно корректен.Я не знаю никаких способов решить эту проблему, кроме того, что всегда использую Object.GetType вместо typeof ().

5 голосов
/ 03 февраля 2011

Причина в том, что вы объявили переменную mess типа BaseMessage.Поэтому, когда вы запрашиваете тип, он возвращает BaseMessage.

Это разница между тем, как GetType и typeof ведут себя.GetType возвращает тип объекта фактический во время выполнения, который может отличаться от типа переменной, которая ссылается на объект, если задействовано наследование (как это имеет место в вашем примере).В отличие от GetType, typeof разрешается в время компиляции в литерал типа точного указанного типа.

public class BaseMessage { }

public class OtherMessage : BaseMessage { }

private BaseMessage getMessage()
{
    return new OtherMessage();
}

private void CheckType<T>(T type)
{
    Console.WriteLine(type.GetType().ToString());   // prints OtherMessage
    Console.WriteLine(typeof(T).ToString());        // prints BaseMessage
}

private void DoChecks()
{
     BaseMessage mess = getMessage();
     CheckType(mess);
}

Вы должны выбрать правильный инструмент для задания.Используйте typeof, если вы хотите получить тип во время компиляции.Используйте GetType, если вы хотите получить тип объекта во время выполнения.

...