创build对象实例而不调用构造函数?
在C#中,有没有办法实例化一个类的实例,而不用调用它的构造函数?
假设类是公共的,并且在第三方库中定义,而构造函数是内部的。 我想这样做的原因很复杂,但是知道是否有可能使用某种C#hackery会有帮助。
注意:我特别不想调用任何构造函数,所以使用reflection来访问内部构造函数不是一个选项。
我没有尝试过,但有一个名为FormatterServices.GetUninitializedObject在反序列化过程中使用的方法。
MSDN的评论说:
因为对象的新实例初始化为零,并且没有构造函数运行,所以该对象可能不会表示该对象认为有效的状态。
其实这听起来像是他们使内部的构造,所以你不能实例化它。 它可能有一个build造者或工厂的方法。
看看这些文章:
防止第三方派生:第一部分
防止第三方派生:第2部分
他们有种解释理由。
与许多人认为的相反,一个构造函数与一个对象的实例化(相当令人误解的术语)没有多大关系。 构造函数是一个特殊的方法,可以在对象的实例化之后调用,以允许该对象正确初始化自身。 在C ++中,对象实例化为对象分配内存,在.NET和Java中,根据字段的types(0,空,假等),它被分配并预初始化为默认值。 然后运行时调用构造函数。 新运算符将这两个独立的操作封装成看起来是单个操作的东西。 如果不使用构造函数就无法创build实例,反序列化在.NET中可能永远无法工作。 也就是说,所谓的ConstructorInfotypes在调用其Invoke(…)方法时既是新的运算符又是构造函数。
有可能通过reflection来访问构造函数,并像这样调用它(但是我不确定它是否能工作,因为构造函数是内部的 – 你必须testing它)。 否则,据我所知,你不能创build一个对象,而无需调用构造函数。
请参阅System.Activator.CreateInstance函数。
编辑:你更新了你的问题,你想构build一个没有构造函数的类。 或者调用一个默认的“Empty Constructor”。
这不能完成,因为如果已经指定了一个,编译器将不会生成默认的构造函数。 但是,为了读者的利益,下面是如何获得内部的,受保护的或私有的构造函数:
假设你的class级叫做Foo:
using System.Reflection; // If the constructor takes arguments, otherwise pass these as null Type[] pTypes = new Type[1]; pTypes[0] = typeof(object); object[] argList = new object[1]; argList[0] = constructorArgs; ConstructorInfo c = typeof(Foo).GetConstructor (BindingFlags.NonPublic | BindingFlags.Instance, null, pTypes, null); Foo foo = (Foo) c.Invoke(BindingFlags.NonPublic, null, argList, Application.CurrentCulture);
丑,但工作。
当然,将构造函数标记为内部函数可能是一个完全合法的理由,所以在用类似的方法来反省这个类之前,你应该真正考虑到你想要的东西。
你所要做的是违反pipe理编程开发的哲学。 .Net框架和C#的构build原则是,只要有可能,对象就应该从其内存中抽象出来。 对象是对象,而不是结构化的字节数组。 这就是为什么你不能投掷对象无效指针。 当对象从底层内存中抽象出来的时候,如果没有调用构造函数就可以存在对象实例,那么从根本上是无效的。
也就是说,.Net框架已经做出让步,事实上,实际上,对象实际上代表着记忆。 有了一定的创造力,就可以在不调用初始值的情况下实例化值types。 但是,如果你觉得你需要这样做,你可能会做错事。
你必须调用一个构造函数来创build一个对象。 如果没有你喜欢的东西,也许你可以使用像Mono项目的Cecil这样的字节码重写库。 它可以在Windows和Linux上运行。 从我看到的一些演示,看起来很酷。 你可以改变方法和各种疯狂的东西的保护水平。
如果类(及其引用的对象的类)是Serializable,则可以使用输出到MemoryStream(创build字节数组byte [])的BinaryFormatter进行序列化,然后反序列化来创build深层副本。 请参阅有关将对象转换为字节数组的问题的答案 。 (但要注意的是,保存字节数组以备后用可能不起作用,IOW不会将字节数组保存到文件或其他永久forms。
我注意到了这个问题的“死亡”,只是为了让更多的读者澄清,并提出了一个最终的答案,当问题发布的时候也许是不可能的。 在这里。
看来你可以实例化一个类,而不使用它的构造函数,通过赋值给它的属性。 以下是MSDN中这种types的实例化的地址http://msdn.microsoft.com/en-us/library/bb397680.aspx 。
这似乎是一种技术,这是不知名的,因为我在CodeProject中的一篇文章中遇到它,然后search它,没有find任何关于它,后来访问MSDN主页,有一个职位,我链接到学科。 所以它似乎是一个未知的主题,而不是一个新的CodeProjectdate2008年5月date。
希望这可以帮助别人,谷歌这一点,并遇到这个问题。
这里没有人比较明确地表示“不能做”的意思。
构造函数是创build对象的东西。 你的问题类似于“我怎样才能build造一座沙堡而不像城堡那样塑造它?” 你不能 – 你只有一堆沙子。
你可以做的最接近的事情是分配一个与你的对象大小相同的内存块:
byte[] fakeObject = new byte[sizeof(myStruct)];
(注:即使这只会在MyStruct中是一个值types)