通过使用Activator.CreateInstance
,我们可以创建类的对象,即使构造函数是私有的。
有没有阻止这个?
答案 0 :(得分:4)
反射一般会破坏封装。 任何类型的任何私有成员(构造函数,方法,属性,字段,您为其命名)都可以使用反射访问(Activator.CreateInstance
属于此保护伞)。
也就是说,如果你希望你的类型不能通过the overload of Activator.CreateInstance
generally used to overcome private
constructors进行实例化,你可以完全摆脱你的类型的无参数构造函数(通过只定义带参数的构造函数)。
但是,您仍然无法对使用指定参数的重载之一做任何事情。
答案 1 :(得分:3)
答案简短:你不能
更详细的答案:阅读.NET code access security。可以在有限信任的环境中运行代码;部分受信任的代码无法绕过访问限制。默认情况下,代码以完全信任的方式运行,而完全信任的代码可以使用反射来访问私有成员。
答案 2 :(得分:1)
有一种方法可以防止它发生,但它并不漂亮:
在私有构造函数中,您可以根据StackTrace
类添加一些检查。在私有构造函数中创建一个新的StackTrace
。调用GetFrames()
并迭代它们,检查是否有任何帧包含来自Activator
类型的调用。在StackFrame
内。您可以通过GetMethod
函数查询方法。返回MethodBase
,它继承自MemberInfo
类。这将具有您关心的DeclaringType
属性。
当您遍历堆栈帧时,如果您注意到调用类型是Activator
类,则您知道通过该方法调用了私有构造函数。
您应该只需要查看两个堆栈框架(跳过当前的堆栈框架)来验证这一点。我相信除Activator
类之外还有另一种方法可以使用反射进行实例化,但我现在还不记得了。
答案 3 :(得分:0)
我知道这是一篇较老的帖子,但我碰到了它,我无法抗拒。
有一种方法可以阻止Activator
访问私有构造函数。例如,在使用嵌套类的Singleton模式类中:
public sealed class SingletonClass
{
SingletonClass()
{
}
public static SingletonClass Instance
{
get
{
return InnerClass.instance;
}
}
class InnerClass
{
static InnerClass()
{
}
internal static readonly SingletonClass instance = new SingletonClass();
}
}