I have a code like shown below
public static Type ToType(Type sType)
{
Assembly assembly = Assembly.Load(SerializableType.AssemblyName);
type = a
It returns null
if the class name is not found, most likely because the Name
property of your type just returns the type name, and not the namespace name to qualify it. Make sure that your Name
property includes the namespace qualifying it as well.
According to the MSDN on Assembly.GetType(string name), it returns:
An object that represents the specified class, or Nothing if the class is not found.
Thus since you're getting null
, it couldn't find the type name, most likely reason is it's either misspelled, or you didn't prepend the type name with the namespace.
This method only searches the current assembly instance. The name parameter includes the namespace but not the assembly.
Or, it's also possible the case is wrong on the type name, there is a version of GetType()
that supports a bool
argument for a case-insensitive name compare as well.
p.s. The namespace is needed because the assembly name may not be an indicator of the namespace. That is, if I had a type in an assembly MySystem.MyClasses.DLL
, this does not mean that the type is necessarily in the MySystem.MyClasses
namespace.
The full MSDN page (always good to see what things throw/return) is here: Assembly.GetType Method(String)
It's evident the assembly exists (or it would return null
and you'd get a NullReferenceException
), so another possibility is you don't have the same version of the assembly you are expecting (i.e. the program using this code has a different version of the assembly then the code generating the data).
This is not working just because you load code from other assembly than you base class assembly. Trying to call this code from other assembly than contains definiton of searched type will result in type resolved to null.
It is reasonable, because you have to provide an assembly qualified type name, i.e. Type.AssemblyQualifiedName, not just type full name itself
If you derived classes defined elsewere in another assembly than base class with code sample, your code from assembly where base class is defined will not work.
This will work
public static Type ToType(Type type, ITypeResolver typeResolver)
{
Assembly assembly = Assembly.Load(SerializableType.AssemblyName);
type = typeResolver.GetType(assembly, sType.AssemblyQualifiedName);
}
You can use a TypeResolver like that (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_
I struggled to find the correctly qualified name of a type in a dll I was trying to use, but found GetTypes() really useful in listing all available. In 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)
Here is an actual example from a UWP app. The app namespace is My_App. Class FooPage is under folder Views. The way to get the Type is the following:
Type typePage = Assembly.GetExecutingAssembly().GetType("My_App.Views.FooPage}");
If you are not sure about the name of your type, use the following code to dump all classes and find the one of interest:
foreach(Type t in Assembly.GetExecutingAssembly().GetTypes())
{
Debug.WriteLine($"{t.Namespace}.{t.Name}");
}
I guess you forgot to mention namespaces. The correct way would be
assembly.GetType(MyNameSpace+sType.Name)
Your type may be non public, by default reflection only works on public types and members, unless you increase your level of security, type will be null.