What is the C# way for dynamically getting the type of object and then creating new instances of it?
E.g. how do I accomplish the result of following Java code开发者_开发百科, but in C#:
MyClass x = (MyClass) Class.forName("classes.MyChildClass").newInstance();
Look at csharp-examples.net/reflection-examples. Basically you have to use typeof()
and Activator.createInstance()
.
Simple example:
namespace Your.Namespace
{
public class Foo
{
public DateTime SixtyDaysFromNow()
{
return DateTime.Now + new TimeSpan(60,0,0,0);
}
}
public class CreateInstance1
{
public static void Main(string[] args)
{
try
{
var x = Activator.CreateInstance(null, "Your.Namespace.Foo");
Foo f = (Foo) x.Unwrap();
Console.WriteLine("Result: {0}", f.SixtyDaysFromNow().ToString("G"));
}
catch (System.Exception exc1)
{
Console.WriteLine("Exception: {0}", exc1.ToString());
}
}
}
}
Call Activator.CreateInstance()
specifying an assembly name, and a classname. The classname must be fully qualified (include all the namespaces). If the assemblyname is null, then it uses the currently running assembly. If the class you want to activate is outside the currently running assembly you need to specify the assembly with the fully qualified name.
To load from a different assembly, you need to use an overload for CreateInstance
that accepts a type, as opposed to a type name; one way to get a type for a given type name is to use Type.GetType()
, specifying the assembly-qualified name.
Most often Activator.CreateInstance()
is done using interface types, so that the instance created can be cast to the interface and you can invoke on the interface type. like this:
interface ISixty
{
DateTime SixtyDaysFromNow();
}
public class Foo : ISixty
{
public DateTime SixtyDaysFromNow()
{
return DateTime.Now + new TimeSpan(60,0,0,0);
}
}
and
var x = Activator.CreateInstance(null, "Your.Namespace.Foo");
ISixty f = (ISixty) x.Unwrap();
Console.WriteLine("Sixty days from now: {0}", f.SixtyDaysFromNow().ToString("G"));
Doing it that way, your app (the activating app) need not be aware of or reference the other assembly explicitly, at compile time.
This question has two parts
How to get the
Type
corresponding to a name?
Sometimes you can useType.GetType(string)
. But unless the type is in mscorlib or the executing assembly you need to specify the name of the assembly in your name.How to create a given Type?
Activatior.CreateInstance
is the answer to this part.
But in your code you already know the class because you can cast to MyClass
. So the question doesn't make much sense.
Be warned about the formulation of this question. The question is "Class.forName() equivalent in .NET?" and this question is not actually answered on this page - the Class.forName() method in Java has one important side effect that the .NET equivalent does not have - that is it actually loads the class. So if you had in Java
Class c = Class.forName("mypackage.PardonMe");
You need TWO statements in C#/.NET to get the full effect:
Type t = Type.GetType("mypackage.PardonMe");
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(t.TypeHandle);
This loads the class without invoking any static methods or creating any instances.
精彩评论