typeof (T) может вернуть ноль - PullRequest
8 голосов
/ 27 июня 2011

При использовании оператора typeof для типа, созданного с помощью TypeBuilder, оператор возвращает ноль.

Мне любопытно, почему это происходит и как это предотвратить.


Я начинаю думать, что это ошибка VS в ближайшем окне, но я не совсем уверен. Сначала очень легко обвинять других.

ОК ... код для воспроизведения вопроса:

    static void Main()
    {
        AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(
            new AssemblyName("MyAssembly"),
            AssemblyBuilderAccess.RunAndSave);
        ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MyModule");
        TypeBuilder typeBuilder = moduleBuilder.DefineType("MyType", TypeAttributes.Public, typeof(ArrayList));

        ArrayList o = (ArrayList)Activator.CreateInstance(typeBuilder.CreateType());

        Console.WriteLine(o.GetType().Name);
    }

Если вы поставите точку останова после переменной o и введете typeof(MyType) в VS Immediate Windows, вы получите проблему.

Ответы [ 2 ]

19 голосов
/ 28 июня 2011

При использовании оператора typeof для типа, созданного с помощью TypeBuilder, оператор возвращает ноль.

Прежде всего, претензия верна. Если вы напишите эту программу, а затем остановите ее в отладчике и скажете «typeof (MyType)» в ближайшем окне, то в результате вы получите «null».

Мне любопытно, почему это происходит

Черт побери из меня. Если бы мне пришлось угадывать, я бы сказал, что, возможно, оценщик выражений обменивается данными с подсистемой отладки CLR, чтобы попытаться получить токен метаданных для типа по его имени, и CLR возвращает некоторый мусорный ноль-токен вместо того, чтобы выдавать ошибку ,

Спешу подчеркнуть, что это предположение; Я на самом деле не отлаживал.

Я начинаю думать, что это ошибка VS в ближайшем окне

Это кажется вероятным. Правильно, что он должен делать, это выдавать ошибку «тип или пространство имен« MyType »недопустимо в этой области». Ошибка почти наверняка будет в оценщике выражений среды выполнения C #, а не в самом непосредственном окне.

Спасибо, что привлекли мое внимание к этой проблеме. Я сообщу об ошибке сопровождающим оценщика выражений, и мы посмотрим, смогут ли они решить эту проблему.

как это предотвратить?

Если больно, когда вы печатаете "typeof (MyType)", тогда прекратите вводить это.

5 голосов
/ 27 июня 2011

Если вы поставите точку останова после переменной 'o' и введите typeof (MyType) в Windows Immediate VS, вы получите проблему.

Ну да.MyType не имеет символа (вы определяете его с помощью отражения!), Поэтому вы не можете использовать typeof на нем.

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

Type MyMethod<T>() where T : class {
    return typeof(T);
}

Type myType = //create type dynamically;

Type myOtherType = //invoke MyMethod with myType as the type parameter

Debug.Assert(myType == myOtherType); //will not fire
...