.NET中的Class.forName()等效?
什么是动态获取对象类型然后创建它的新实例的C#方式?
例如,我如何实现遵循Java代码的结果,但在C#中:
MyClass x = (MyClass) Class.forName("classes.MyChildClass").newInstance();
看看csharp-examples.net/reflection-examples 。 基本上你必须使用typeof()
和Activator.createInstance()
。
这个问题有两个部分
-
如何获取与名称对应的
Type
?
有时您可以使用Type.GetType(string)
。 但除非类型在mscorlib或正在执行的程序集中,否则您需要在名称中指定程序集的名称。 -
如何创建给定的类型?
Activatior.CreateInstance
是这部分的答案。
但是在你的代码中你已经知道了这个类,因为你可以转换为MyClass
。 所以这个问题没有多大意义。
简单的例子:
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"));
这样做,您的应用程序(激活应用程序)无需在编译时明确地知道或引用其他程序集。
请注意这个问题的制定。 问题是“.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);
这会加载类而不调用任何静态方法或创建任何实例。