C# 使用私有构造函数实例化内部类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2023193/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Instantiating Internal class with private constructor
提问by sunny
I am trying to use reflection to create instance of a class. But it is sealed internal and has private constructor. I wonder how can i initiaise it and as its part of framework, I can only use reflection to take it out?
我正在尝试使用反射来创建类的实例。但它是内部密封的并且具有私有构造函数。我想知道如何初始化它,作为框架的一部分,我只能使用反射将其取出?
internal sealed class ABC
{
private ABC(string password){}
public static ABC Create(string password){};
}
Added: System.ServiceModel.Channels.SelfSignedCertificate is the internal class I am trying to use
添加:System.ServiceModel.Channels.SelfSignedCertificate 是我尝试使用的内部类
采纳答案by Lasse V. Karlsen
First of all, the very fact that it is internal means you're not supposed to be doing what you want to do.
首先,它是内部的这一事实意味着你不应该做你想做的事。
You should seriously try to find an alternate route to what you want to accomplish.
你应该认真地尝试找到一条替代路线来完成你想要完成的事情。
Unfortunately, you don't tell us what you want to accomplish, only the next step you think you want to do, so that's what I can help you with.
不幸的是,你没有告诉我们你想完成什么,只有你认为你想做的下一步,所以这就是我可以帮助你的。
This code will work, and accesses the public static method:
此代码将起作用,并访问公共静态方法:
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" });
Note that this relies on having access to another type in the same assembly, that is public. If you don't have that, you need to get hold of the Assembly object that contains the type.
请注意,这依赖于访问同一程序集中的另一种类型,即公共类型。如果没有,则需要获取包含该类型的 Assembly 对象。
回答by Brett Bim
You can't instantiate classes with private constructors unless it's a nested class.
除非它是嵌套类,否则不能使用私有构造函数实例化类。
http://msdn.microsoft.com/en-us/library/kcfb85a6%28VS.71%29.aspx
http://msdn.microsoft.com/en-us/library/kcfb85a6%28VS.71%29.aspx
回答by Jon Skeet
EDIT: I hadn't noticed that you mentioned that the type you're trying to initialize is part of the .NET framework. I thought it was one of your own types, just referenced from elsewhere.
编辑:我没有注意到您提到您尝试初始化的类型是 .NET 框架的一部分。我认为它是您自己的类型之一,只是从其他地方引用。
I would strongly urge you not to attempt this. Microsoft are perfectly at liberty to change or remove internal classes between framework releases - your code will be incredibly brittle if you rely on implementation details like this.
我强烈建议您不要尝试这样做。Microsoft 完全可以自由地在框架版本之间更改或删除内部类 - 如果您依赖这样的实现细节,您的代码将非常脆弱。
Change your design to avoid needing to do this.
更改您的设计以避免需要这样做。
Original answer:
原答案:
Yes, you'd have to use reflection - like this:
是的,你必须使用反射 - 像这样:
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" });
}
}
Note that violating access modifiers in this way requires the ReflectionPermissionFlag.MemberAccess
permission. If you know there will be a static method called Create
, you'd be better off invoking thatvia reflection:
请注意,以这种方式违反访问修饰符需要ReflectionPermissionFlag.MemberAccess
权限。如果您知道将有一个名为 的静态方法Create
,则最好通过反射调用它:
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"});
}
}
回答by jason
If it's internal
to an assembly that is not yours and the constructor is marked as private
, the author of the assembly is trying very hard to keep you from creating the object.
如果它internal
指向一个不属于您的程序集并且构造函数被标记为private
,则程序集的作者会非常努力地阻止您创建该对象。
The below is really evil as you're relying on non-public classes and methods which could change on you without advance notice.
下面的内容真的很糟糕,因为您依赖于非公共类和方法,这些类和方法可能会在没有提前通知的情况下改变您。
Added:
System.ServiceModel.Channels.SelfSignedCertificate
is theinternal
class I am trying to use
补充:
System.ServiceModel.Channels.SelfSignedCertificate
是internal
我试图使用的类
Do not do this. The framework could change under you in the blink of an eye ruining your code and all of your hard work.
不要这样做。框架可能会在眨眼之间改变,破坏你的代码和你所有的辛勤工作。
That said, you could do this:
也就是说,你可以这样做:
MethodInfo method = Type.GetType(assemblyQualifiedName).GetMethod("Create");
ABC o = (ABC)method.Invoke(null, new[] { "test" });
This invokes the static
method Create
. Another option is
这将调用static
方法Create
。另一种选择是
MethodInfo method = Type.GetType(assemblyQualifiedName).GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance,
null,
new[] { typeof(string) },
null
);
ABC o = (ABC)method.Invoke(new[] { "test" });
which uses reflection to load the constructor that accepts a string
as a parameter.
它使用反射来加载接受 astring
作为参数的构造函数。
An easy way to get the assembly-qualified name is
获取程序集限定名称的一种简单方法是
string name = typeof(somePublicType).Assembly.GetType("Namespace.ABC");
where somePublicType
is a type that is public and in the same assembly as ABC
.
其中somePublicType
是公共类型并且与ABC
.
回答by jHymana
Use the Activator class to instantiate it
使用 Activator 类来实例化它
Activator.CreateInstance(myType, true);