2015-09-28 156 views
2

我想知道如何获取任意类的字段的默认值。获取一个字段的默认值

例如,

public class Example 
{ 
    public int a = 10; 
} 

我要当只给出typeof(Example)获得价值10

这个默认值很有用,因为我正在编写一个函数来为任何类型创建一个非空的默认实例。将实例初始化为声明中给出的值将会很好。

请注意,通过默认构造函数创建实例并获取值不是我的选择,因为我希望我正在使用的函数可以应用于具有或不具有默认构造函数的类。

另外,DefaultValueAttribute也不适合我。据我所知,属性只能有几种类型作为它的参数。所以我无法获得自定义类型字段的默认值。

编辑1:

我知道这个问题似乎是Get default value of class member重复,但事实并非如此。在引用的问题中,OP满意于使用构造函数来获取类的实例。但就我而言,我无法确定我正在处理的类是否存在默认的构造函数。

我正在写一个默认值生成器,因为我需要一个任意类型的假对象。也就是说,没有关于这种类型将会如何的假设。伪造的对象将通过GUI进行检查,并且用户可以编辑检查器中暴露的字段的值。这里的任意类型对我很重要,因为检查员不仅应该处理由我定义的类型,而且还处理库中定义的类型。此外,虚假的对象不应该是空的或检查员会炸毁,大声笑。

FormatterServices.GetSafeUninitializedObject得到一个可以接受的假对象,因为它分配内存块并将它们初始化为零。但是我觉得如果假对象可以进一步初始化,这样字段可以在检查器中显示它们的默认值会更好。

感谢Patrick Hofman提醒我,我所说的“默认值”不是真正的默认值,而是一个将在构造函数中进行评估的表达式。这就是说,我仍然想知道是否有可能获取字段初始化表达式和事件评估它。

我认为应该有这样做的方式,因为反编译器(如ILSpy)可以在反编译结果中显示字段初始值设定项。

+3

如果类型的构造函数分配另一个值会怎么样?那么你的“默认”价值是毫无意义的。 –

+0

你能用吗?(新的例子())。a,不是吗? – enkryptor

+2

没有创建类型的实例或像属性那样依赖元数据的做法没有任何理智的方法。 – vcsjones

回答

3

您只能获取常量的值,而不是任何其他类型的变量,因为它们需要有一个初始化类来检索一个值,这些值不再是实际的默认值,而只是当前值。

以前重复的Get default value of class member告诉你该怎么做,如果你放弃不要创建实例约束。

这个呢?

public class Example 
{ 
    public readonly DateTime a = DateTime.Now; 
} 

你能告诉我这个字段的默认值是什么吗?即使可以,它也不是真正的默认值,它是某个时间点某个变量的评估值。

+3

最后一个例子中的默认值是'09/28/2015 16:07:08',不等#09/28/2015 16:07:20',没有'09/28/2015 16:07:23'。 .. –

+0

你钉了它! @Jeppe –

1

您可以检查IL代码,并查找名为.ctor(这些是实例构造函数)的成员。

然后找一个这确实call另一个Example::.ctor超载,而是调用基类的构造函数,你的情况[mscorlib]System.Object::.ctor()。 (如果不存在一个实例字段初始化不可达(病理情况下)!)

然后,该成员的IL内,现场作业stfld之前来电来人基类.ctor,是字段初始值设定项。瞧!

相关问题