是否可以在已创建的实例上直接调用构造函数
本文关键字:调用 构造函数 实例 创建 是否 | 更新日期: 2023-09-27 18:32:13
我知道你可以直接调用一个类型的静态构造函数,我知道你可以创建一个对象的实例而不调用构造函数,但是有没有办法在已经存在的实例上运行一个类型的构造函数(.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");
}
我知道我永远不需要这样做,我更想知道是否可以在已经创建的对象上重新调用构造函数/初始值设定项。
ConstructorInfo
对象重载MethodBase
的Invoke
方法,但不隐藏继承的方法。您只需确保传递正确的实例即可。例:
using System;
using System.Reflection;
class A
{
public int i;
public A()
{
Console.WriteLine("A()");
}
private A(int j)
{
Console.WriteLine("A(" + j + "): i = " + i);
}
}
static class Program
{
static void Main(string[] args)
{
var a = new A();
a.i = 3;
var constructor = a.GetType().GetConstructor(BindingFlags.Instance | BindingFlags.Public |BindingFlags.NonPublic, null, new Type[] { typeof(int) }, null);
constructor.Invoke(a, new object[] { 3 });
}
}
但是,正如此答案还显示的那样,这不会重置对象的任何字段,并且可能会在编写构造函数时假设所有字段都保留为其默认值。如果你有这样一个构造函数,你肯定需要确保你要么不会弄乱任何字段,要么重新设置它们(如果有的话)。如果你有一个尚未调用构造函数的未初始化对象,那应该没问题。
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
保持不变。这是因为a&b是在ctor中定义的,虽然不明显,但d也是如此(在对象级别分配的属性实际上是在调用ctor时分配的)。