.NET中的Class.forName()等效?

时间:2011-05-12 14:24:19

标签: java c# reflection

动态获取对象类型然后创建它的新实例的C#方式是什么?

E.g。如何实现遵循Java代码的结果,但在C#中:

MyClass x = (MyClass) Class.forName("classes.MyChildClass").newInstance();

4 个答案:

答案 0 :(得分:8)

看看csharp-examples.net/reflection-examples。基本上,您必须使用typeof()Activator.createInstance()

答案 1 :(得分:5)

这个问题有两个部分

  1. 如何获取与名称对应的Type? 有时您可以使用Type.GetType(string)。但除非类型在mscorlib或正在执行的程序集中,否则您需要在名称中指定程序集的名称。

  2. 如何创建给定的类型?
    Activatior.CreateInstance是这部分的答案。

  3. 但是在你的代码中你已经知道了这个类,因为你可以转换为MyClass。所以这个问题没有多大意义。

答案 2 :(得分:4)

简单示例:

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());
            }
        }
    }
}

调用Activator.CreateInstance()指定程序集名称和类名。类名必须是完全限定的(包括所有名称空间)。如果assemblyname为null,则它使用当前运行的程序集。如果要激活的类在当前运行的程序集之外,则需要使用完全限定名称指定程序集。

要从其他程序集加载,您需要使用接受类型的CreateInstance重载,而不是类型名称;获取给定类型名称的类型的一种方法是使用Type.GetType(),指定程序集限定名称。

大多数情况下Activator.CreateInstance()是使用接口类型完成的,因此创建的实例可以强制转换为接口,您可以在接口类型上调用。像这样:

    interface ISixty
    {
        DateTime SixtyDaysFromNow();
    }

    public class Foo : ISixty
    {
        public DateTime SixtyDaysFromNow()
        {
            return DateTime.Now + new TimeSpan(60,0,0,0);
        }
    }

  var x = Activator.CreateInstance(null, "Your.Namespace.Foo");
  ISixty f = (ISixty) x.Unwrap();
  Console.WriteLine("Sixty days from now: {0}", f.SixtyDaysFromNow().ToString("G"));

这样做,您的应用程序(激活应用程序)无需在编译时明确地知道或引用其他程序集。

答案 3 :(得分:3)

警告这个问题的提法。问题是“.NET中的Class.forName()等效?”并且这个问题在这个页面上实际上没有得到解答 - Java中的Class.forName()方法有一个重要的副作用,即.NET等价物没有 - 也就是它实际加载了类。所以如果你有Java的话

Class c = Class.forName("mypackage.PardonMe");

您需要在C#/ .NET中使用两个语句才能获得完整的效果:

Type t = Type.GetType("mypackage.PardonMe");
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(t.TypeHandle);

这会在不调用任何静态方法或创建任何实例的情况下加载类。