在C#中,有没有一种方法可以实例化一个类的实例而不调用其构造函数?
假设该类是公共的,并且在第3方库中定义,并且构造函数是内部的。我想要这样做的原因很复杂,但是了解使用某种C#黑客是否可能会有所帮助。
注意:我特别不想调用任何构造函数,因此不能使用反射来访问内部构造函数。
在C#中,有没有一种方法可以实例化一个类的实例而不调用其构造函数?
假设该类是公共的,并且在第3方库中定义,并且构造函数是内部的。我想要这样做的原因很复杂,但是了解使用某种C#黑客是否可能会有所帮助。
注意:我特别不想调用任何构造函数,因此不能使用反射来访问内部构造函数。
Answers:
我没有尝试过此方法,但是在反序列化过程中使用了一种称为FormatterServices.GetUninitializedObject的方法。
来自MSDN的评论说:
因为该对象的新实例被初始化为零,并且没有运行构造函数,所以该对象可能不表示该对象认为有效的状态。
与许多人的看法相反,构造函数与对象的实例化根本没有多大关系(相当误导性的术语)。构造函数是一种特殊的方法,可以在实例化对象之后调用该方法,以允许该对象正确地初始化自身。在C ++对象实例化中,为对象分配内存。在.NET和Java中,实例化将根据字段的类型(0,null,false等)分配并预先初始化为默认值。然后运行时调用构造函数。new运算符将这两个单独的动作封装为一个单一的动作。如果不使用构造函数无法创建实例,则反序列化将无法在.NET中工作。就是说,所谓的ConstructorInfo类型在调用其Invoke(...
编辑:您更新了您的问题,您想构造一个没有构造函数的类。或调用默认的“空构造函数”。
这无法完成,因为如果已经指定了默认构造函数,编译器将不会生成默认构造函数。但是,为了读者的利益,以下是获取内部,受保护或私有构造函数的方法:
假设您的班级称为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);
丑陋,但是行得通。
当然,将构造函数标记为内部构造可能是完全合理的理由,因此在滥用该类并进行反思之前,您应该真正考虑所需的对象。
如果该类(及其引用的对象的类)是可序列化的,则可以使用输出到MemoryStream的BinaryFormatter进行序列化(创建字节数组byte [])来进行深度复制,然后反序列化。有关将对象转换为字节数组的信息,请参见此问题的答案。(但请注意-保存字节数组以在以后/其他地方使用可能不起作用。IOW不会将字节数组保存为文件或其他持久形式。)
我注意到了该主题的“死气沉沉”,但只是为了进一步澄清读者的意见,并提出了一个最终的答案,而这个问题在发布问题时是不可能的。来了
似乎可以通过将值分配给其属性来实例化一个类而无需使用其构造函数。这是该类型的实例化在MSDN中的操作方法http://msdn.microsoft.com/zh-cn/library/bb397680.aspx的地址。
似乎这是一种并不为人所知的技术,因为我在CodeProject中的一篇文章中遇到了它,然后在Google上搜索了它,却没有找到任何有关它的信息,后来访问了MSDN主页,并且有一篇帖子将我链接到了该确切的位置。学科。因此,似乎这是一个未知主题,而不是新主题,因为CodeProject帖子上的日期为2008年5月。
希望这对谷歌的帮助,并遇到这个问题的人。