开发者

Class.forName() equivalent in .NET?

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

  1. How to get the Type corresponding to a name?
    Sometimes you can use Type.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.

  2. 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜