我正在处理.NET测试数据构建器的功能请求。我需要能够实例化只有私有无参数构造函数的类。
例如,我可能需要实例化以下类:
public class MyClass()
{
private MyClass(){}
}
对于大多数其他类,我使用以下代码:
(T)Activator.CreateInstance(typeof(T), true)
但是对于只有私有无参数构造函数的类,我使用以下代码:
(T)FormatterServices.GetUninitializedObject(typeof(T))
不幸的是,我还要求Silverlight中的这项工作,不幸的是Silverlight目前不包含System.Runtime.Serialization.FormatterServices。
有没有人知道Silverlight实现中的任何内容可以让我解决这个问题?如果做不到,有谁知道如何实现我自己的这个方法版本?
答案 0 :(得分:1)
您无法从外部实例化该类。据推测,它是故意设计的,因此您无法实例化它。
我希望有一些静态的获取实例的方法,例如单例属性或工厂方法......但如果你需要能够用任何类型执行此操作,那不行。
基本上,你需要重新考虑你的设计 - 不要试图颠覆班级作者的意愿。
答案 1 :(得分:1)
如果您的课程定义如下:
public class MyClass
{
private MyClass(){}
}
你可以使用我在我的问题中提到的以下代码来实例化它:
(T)Activator.CreateInstance(typeof(T), true)
附加参数true,使用type's default constructor创建实例。
事实证明,我甚至不需要首先使用FormatterServices.GetUninitializedObject。
但是,我要感谢Jon Skeet的回答,因为它帮助我质疑我的设计并深入挖掘了Activator.CreateInstance并增加了对类实例化的理解。
目前,我的解决方案是删除FormatterServices的使用,如果类型创建出现问题,只允许抛出异常。
目前,从我所知,使用(T)Activator.CreateInstance(typeof(T),true)我应该能够构建我遇到的大多数类,除了以下内容:
public MyClass()
{
int a;
private MyClass(int a)
{
this.a = a;
}
}
然而,事实证明有一种方法建议here能够实例化这个类:
int argA = 100;
Type type = typeof(MyClass);
ConstructorInfo c = type.GetConstructor(BindingFlags.NonPublic
| BindingFlags.Instance, null, new Type[] { typeof(int) }, null);
MyClass o = (MyClass)c.Invoke(new Object[] { argA });
但是在考虑了Jon所说的内容后,我认为这对使用我正在增强的测试数据构建器的任何人都没有多大用处。如果有人为了防止一个类被实例化而遇到了很多麻烦,那么也许它不应该通过类设计者提供的方法来构建。
答案 2 :(得分:0)
您可以使用反射 但
来实现你应该真的决定你做的是否正确。正如其他人所说的那样,这个类可能不是那样实例化的。但我知道,在极少数情况下可能需要这样做。
您需要完全信任,即浏览器外运行。你不能在浏览器中这样做。
以下是代码:
var privateConstructors = typeof(MyClass).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance);
foreach (var constr in privateConstructors)
{
var obj = constr.Invoke(new object[0]);
return;
}
throw new Exception("private constructor not found");