我知道你可以直接调用static constructor of a type和I know that you can create an instance of an object without calling the constructor,但有没有办法在已经存在的实例上运行类型(.ctor
)的构造函数?
我正在寻找类似的东西:
public static void Reinitialize<T>(T instance)
{
var initializer = typeof(T).GetHiddenConstructorThatDoesntNew(typeof(int), typeof(string));
// call the constructor (int, string) on instance
initializer.Invoke(instance, 7, "Bill");
}
我知道我永远不应该真的需要这样做,我更想知道是否可能在已创建的对象上重新调用构造函数/初始值设定项。
答案 0 :(得分:8)
ConstructorInfo
对象重载MethodBase
的{{1}}方法,但不隐藏继承的方法。您只需确保传递正确的实例即可。例如:
Invoke
但是,正如这个答案也表明的那样,没有重置任何对象的字段,并且可以编写构造函数,假设所有字段都保留在他们的默认值。如果您有这样的构造函数,那么您肯定需要确保不要弄乱任何字段,或者如果有的话重新设置它们。如果你有一个未初始化的对象,但尚未调用构造函数,那应该没问题。
答案 1 :(得分:5)
var ctor = typeof(T).GetConstructor(new[]{ typeof(int), typeof(string) });
ctor.Invoke(instance, new Object[]{ 7, "Bill" });
您正在寻找.GetConstructor
。
给出以下对象:
public class Foo
{
public Int32 a;
public String b;
public DateTime c;
public Double d = 5318008;
public Foo(Int32 a, String b)
{
this.a = a;
this.b = b;
}
}
以标准方式调用ctor会产生以下结果:
var foo = new Foo(42, "Hello, world!") { new DateTime(2014, 11, 26) };
// foo {
// a=42,
// b="Hello, world!",
// c=11/27/2014 12:00:00 AM
// d = 5318008
// }
现在让'改变d:
foo.d = 319009;
// foo {
// a=42,
// b="Hello, world!",
// c=11/27/2014 12:00:00 AM
// d=319009
// }
再次致电ctor:
typeof(Foo)
.GetConstructor(new[]{ typeof(Int32), typeof(String) }).
.Invoke(foo, new Object[]{ 84, "World, Hello!" });
// foo {
// a=84,
// b="World, hello!",
// c=11/27/2014 12:00:00 AM // only unchanged property
// d=5318008
// }
请注意c
保持不变。这是因为&amp; b在ctor中定义,虽然不是很明显,但d也是如此(在调用ctor时实际分配了在对象级别分配的属性)。