Когда `Assembly.GetType (name)` возвращает `null`? - PullRequest
6 голосов
/ 15 ноября 2011

У меня есть код, подобный показанному ниже

public static Type ToType(Type sType)
{    
    Assembly assembly = Assembly.Load(SerializableType.AssemblyName);
    type = assembly.GetType(sType.Name);
}

ОБНОВЛЕНИЕ

В пользовательском интерфейсе, если я устанавливаю значение для базового класса, нет проблем, потому что их сборка создает нормальный способ,но если вы установите значение для определенного пользователем класса, их сборка будет выглядеть иначе, как показано ниже

Ответы [ 6 ]

6 голосов
/ 15 ноября 2011

Возвращает null, если имя класса не найдено, скорее всего потому, что свойство Name вашего типа просто возвращает имя типа, а не имя пространства имен для его определения.Убедитесь, что ваше свойство Name включает и пространство имен, которое его квалифицирует.

В соответствии с MSDN для Assembly.GetType (имя строки) возвращает:

Объект, которыйпредставляет указанный класс, или Nothing, если класс не найден.

Таким образом, поскольку вы получаете null, он не может найти имя типа, скорее всего, причина в том, что он либо неправильно написан,или вы не добавляли имя типа к пространству имен.

Этот метод ищет только текущий экземпляр сборки.Параметр name включает пространство имен, но не сборку.

Или, возможно, неправильный регистр имени типа, существует версия GetType(), которая поддерживает аргумент bool длясравнение имени без учета регистра также.

ps Пространство имен необходимо, поскольку имя сборки не может быть индикатором пространства имен.То есть, если у меня был тип в сборке MySystem.MyClasses.DLL, это не значит, что тип обязательно находится в пространстве имен MySystem.MyClasses.

Полная страница MSDN (всегда приятно видеть, что вещи выбрасывают /return) здесь: Метод Assembly.GetType (String)

Очевидно, что сборка существует (или она вернет null, и вы получите NullReferenceException), поэтому другойвозможно, у вас нет той версии сборки, которую вы ожидаете (т.е. программа, использующая этот код, имеет другую версию сборки, чем код, генерирующий данные).

0 голосов
/ 12 апреля 2018

Это не работает только потому, что вы загружаете код из другой сборки, чем из сборки базового класса. Попытка вызова этого кода из другой сборки, которая не содержит определения искомого типа, приведет к типу, разрешенному в нуль.

Это разумно, потому что вы должны предоставить полное имя типа сборки, то есть Type.AssemblyQualifiedName, а не просто ввести само полное имя

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

Это будет работать


public static Type ToType(Type type, ITypeResolver typeResolver)
{    
    Assembly assembly = Assembly.Load(SerializableType.AssemblyName);
    type = typeResolver.GetType(assembly, sType.AssemblyQualifiedName);
}

Вы можете использовать TypeResolver вот так (C # 7.2)

public interface ITypeResolver
{
    string GetName(Type type);
    Type GetType(Assembly assembly, string typeName);
}

class TypeResolver : ITypeResolver
{
    public string GetName(Type type) => type.AssemblyQualifiedName;
    public Type GetType(Assembly assembly, string typeName) =>
        assembly.GetType(typeName) ?? Type.GetType(typeName);
}

MSDN:

https://docs.microsoft.com/ru-ru/dotnet/api/system.type.gettype?view=netcore-2.1#System_Type_GetType_System_String_

0 голосов
/ 05 марта 2018

Вот фактический пример из приложения UWP.Пространство имен приложения - My_App.Класс FooPage находится в папке Views.Способ получения типа следующий:

Type typePage = Assembly.GetExecutingAssembly().GetType("My_App.Views.FooPage}");

Если вы не уверены в названии вашего типа, используйте следующий код, чтобы вывести все классы и найти интересующий вас:

foreach(Type t in Assembly.GetExecutingAssembly().GetTypes())
{
    Debug.WriteLine($"{t.Namespace}.{t.Name}");
}
0 голосов
/ 04 сентября 2015

Я изо всех сил пытался найти правильно определенное имя типа в dll, который я пытался использовать, но нашел GetTypes () действительно полезным при перечислении всех доступных.В VB:

    Dim t As Type() = assem.GetTypes()
    Dim s As String = ""
    For i As Integer = 0 To t.Length - 1
        s = s & t(i).FullName & vbCrLf
    Next i
    MsgBox(s)
0 голосов
/ 13 мая 2014

Полагаю, вы забыли упомянуть пространства имен. Правильный путь будет

assembly.GetType(MyNameSpace+sType.Name)
0 голосов
/ 15 ноября 2011

Ваш тип может быть закрытым, по умолчанию отражение работает только с открытыми типами и членами, если только вы не повысите уровень безопасности, тип будет нулевым.

...