在工作中阅读现有代码,我想知道这怎么可行。我在程序集中定义了一个类:
[Serializable]
public class A
{
private readonly string _name;
private A(string name)
{
_name = name;
}
}
在另一个集会中:
public void f(Type t) {
object o = Activator.CreateInstance(t);
}
和那个简单的电话f(typeof(A))
我期待一个关于缺少无参数构造函数的例外,因为AFAIK,如果声明了ctor,编译器不应该生成默认的公共无参数构造函数。
此代码在.NET 2.0下运行。
[编辑]我很抱歉,但我误读了实际代码......我提供的示例并没有说明。我接受了JonH的答案,因为它提供了很好的信息。
答案 0 :(得分:24)
另一种选择是:
object obj = System.Runtime.Serialization.FormatterServices
.GetUninitializedObject(t);
在内存中创建对象,但不运行任何构造函数。吓人。
答案 1 :(得分:10)
请参阅:Creating instance of type without default constructor in C# using reflection
这也是未来,这是关于C#4.0:
微软于2010年1月4日发表于 下午2:08
我们已经审核了您的错误 已经确定了那种行为 你描述的是设计。我们现在 归档此问题。谢谢你的使用 Visual Studio和.Net Framework!Activator.CreateInstance有很多重载 仅采用单个类型参数 调用默认的无参数 构造函数。采取的建设者 可选参数,例如 你的例子不是默认的 构造函数。要调用它们,你需要 到:
- 使用带参数数组的重载
- 传入Type.Missing作为参数
- 在BindingFlags
中指定OptionalParamBinding 醇>以下是一个例子:
Activator.CreateInstance(typeof(MyClassName), BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.Instance | BindingFlags.OptionalParamBinding, null, new Object[] {Type.Missing}, null);
谢谢,
苏伟涛微软公司
答案 2 :(得分:0)
这对你来说可能不太可行,但最简单的方法是在类型之后传递参数列表:
Activator.CreateInstance(t,“name”);
你会想到f()真正想要做什么。是否应该实例化A类型的对象?它将实例化哪些其他类?
一种可能性是在f()中有一个switch语句,它将正确的参数传递给A类的CreateInstance()。这不会扩展,但这对你来说可能不是问题。
答案 3 :(得分:0)
CreateInstance
有两种令人困惑的风格:一种将对象类型System.Type
作为参数,另一种采用< strong>类型参数 T
。
第一个:
object Activator.CreateInstance(type As Type) { }
第二个:
T Activator.CreateInstance<T>() { }
第二个是一个不适用于没有公共无参数构造函数的类。
请注意,即使使用第二个也几乎没有意义;在任何使用它的情况下,最好在你的类上有一个where T : new()
约束,只需使用T
的构造函数。
一般情况下,没有用 应用程序代码中的
CreateInstance
, 因为必须知道类型 编译时间。如果类型已知 编译时,正常实例化 语法可以使用(new
运算符 Visual Basic中的C#,New
,gcnew
中 C ++)。
编辑:我可能说得太早;似乎第一个版本也不应该工作。