使用私有构造函数实例化内部类

我正在尝试使用reflection来创建类的实例。 但它内部密封,并有私人构造。 我想知道如何初始化它,作为框架的一部分,我只能用reflection把它拿出来?

internal sealed class ABC { private ABC(string password){} public static ABC Create(string password){}; } 

补充:System.ServiceModel.Channels.SelfSignedCertificate是我尝试使用的内部类

首先,它是内部的事实意味着你不应该做你想做的事情。

你应该认真地尝试找到你想要完成的替代路线。

不幸的是,你没有告诉我们你想要完成什么,只是你认为你想要做的下一步,所以这就是我可以帮助你的。

此代码将起作用,并访问公共静态方法:

 Type t = typeof(SomeOtherTypeInSameAssembly) .Assembly.GetType("ClassLibrary1.ABC"); MethodInfo method = t.GetMethod("Create", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(String) }, new ParameterModifier[0]); Object o = method.Invoke(null, new Object[] { "test" }); 

请注意,这依赖于访问同一程序集中的另一种类型,即公共。 如果没有,则需要获取包含该类型的Assembly对象。

编辑:我没有注意到你提到你尝试初始化的类型是.NET框架的一部分。 我认为这是你自己的类型之一,只是从其他地方引用。

我强烈建议你不要这样做 。 微软可以自由地在框架版本之间更改或删除内部类 – 如果您依赖这样的实现细节,您的代码将非常脆弱。

更改您的设计以避免需要这样做。


原始答案:

是的,你必须使用reflection – 像这样:

 using System; using System.Reflection; internal sealed class ABC { private ABC(string password) { Console.WriteLine("Constructor called"); } } public class Test { static void Main() { ConstructorInfo ctor = typeof(ABC).GetConstructors (BindingFlags.Instance | BindingFlags.NonPublic)[0]; ABC abc = (ABC) ctor.Invoke(new object[] { "test" }); } } 

请注意,以这种方式违反访问修饰符需要ReflectionPermissionFlag.MemberAccess权限。 如果你知道会有一个名为Create的静态方法,你最好通过reflection来调用

 using System; using System.Reflection; internal sealed class ABC { private ABC(string password) { Console.WriteLine("Constructor called"); } public static ABC Create(string password) { return new ABC(password); } } public class Test { static void Main() { MethodInfo method = typeof(ABC).GetMethod("Create", BindingFlags.Static | BindingFlags.Public); ABC abc = (ABC) method.Invoke(null, new object[]{"test"}); } } 

如果它是不属于你的程序集的internal ,并且构造函数被标记为private ,则程序集的作者正在努力阻止您创建该对象。

以下是非常邪恶的,因为你依赖非公开的课程和方法,如果没有提前通知可能会改变你。

补充: System.ServiceModel.Channels.SelfSignedCertificate是我尝试使用的internal

不要这样做 。 眨眼之间,框架可能会在你身边发生变化,破坏你的代码和你所有的辛勤工作。

那说,你可以这样做:

 MethodInfo method = Type.GetType(assemblyQualifiedName).GetMethod("Create"); ABC o = (ABC)method.Invoke(null, new[] { "test" }); 

这将调用static方法Create 。 另一种选择是

 MethodInfo method = Type.GetType(assemblyQualifiedName).GetConstructor( BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(string) }, null ); ABC o = (ABC)method.Invoke(new[] { "test" }); 

它使用reflection来加载接受string作为参数的构造函数。

获取程序集限定名称的简单方法是

 string name = typeof(somePublicType).Assembly.GetType("Namespace.ABC"); 

其中somePublicType是一个公共类型,与ABC在同一个程序集中。

除非是嵌套类,否则不能使用私有构造函数实例化类。

http://msdn.microsoft.com/en-us/library/kcfb85a6%28VS.71%29.aspx

使用Activator类来实例化它

 Activator.CreateInstance(myType, true);