我想知道如何获取任意类的字段的默认值。
例如,
public class Example
{
public int a = 10;
}
我希望仅在10
给出时获得值typeof(Example)
。
这个默认值很有用,因为我正在编写一个函数来为任何类型创建一个非null的默认实例。将实例初始化为声明中给出的值会很好。
请注意,通过默认构造函数创建实例并获取值不是我的选项,因为我希望我正在处理的函数可以应用于带或不带默认构造函数的类。
另外,DefaultValueAttribute
对我来说也不是一个选择。据我所知,属性只能采用几种类型作为参数。所以我无法获得自定义类型字段的默认值。
编辑1:
我知道这个问题似乎是Get default value of class member的重复,但事实并非如此。在引用的问题中,OP满足于使用构造函数来获取类的真实实例。但就我而言,我无法确定我正在处理的类是否存在默认构造函数。
我正在写一个默认值生成器,因为我需要一个任意类型的假对象。也就是说,没有假设类型将如何。将通过GUI检查虚假对象,并且用户可以编辑检查器中公开的字段的值。这里任意类型对我很重要,因为检查器不仅应该处理由我定义的类型,还应该处理库中定义的类型。此外,假对象永远不应为空或检查员会爆炸,大声笑。
FormatterServices.GetSafeUninitializedObject
为我提供了一个可接受的假对象,因为它分配了内存块并将它们初始化为零。但我觉得如果可以进一步初始化虚假对象会更好,因此字段可以在检查器中显示其默认值。
感谢Patrick Hofman提醒我"默认值"我所说的不是真正的默认值,而是一个将在构造函数中进行求值的表达式。话虽这么说,我仍然想知道是否有可能获取字段初始化表达式和事件评估它。
我认为应该有这样做的方法,因为ILSpy等反编译器可以在反编译结果中显示字段初始值设定项。
答案 0 :(得分:3)
你只能获得常量的值,而不能获得任何其他类型的变量,因为它们需要有一个初始化的类来检索一个值,它不再是真正的默认值,只是当前值。
之前重复的Get default value of class member告诉您如果放弃不创建实例约束该怎么做。
这个怎么样?
public class Example
{
public readonly DateTime a = DateTime.Now;
}
你能告诉我这个字段的默认值是什么吗?即使你可以,它也不是真正的默认值,它是某个时间点某个变量的评估值。
答案 1 :(得分:1)
您可以检查IL代码,并查找名为.ctor
的成员(这些是实例构造函数)。
然后找到一个 不 call
另一个Example::.ctor
重载,但在你的情况下调用基类构造函数{{ 1}}。 (如果不存在,则实例字段初始值设定项无法访问(病态情况)!)
然后,在此成员的IL内, 之前 对基类[mscorlib]System.Object::.ctor()
的调用的字段分配stfld
是字段初始化程序。瞧!