繁体   English   中英

获取PropertyInfo的默认值而不实例化对象?

[英]Get the default value of a PropertyInfo without instantiating the object?

我得到了这个有效的代码(简化):

Assembly lib = Assembly.LoadFile("C:\\mydll.dll");
var libType = lib.GetTypes();
Type mvType = libType[0];
PropertyInfo WidthProperty = mvType.GetProperty("Width");

但是,我想用类似的代码访问默认值

var WidthPropertyValue = WidthProperty.GetValue(???, null);

问题是我们无法使用Activator.CreateInstance实例化对象,导致构造函数需要加载整个巨大的项目才能工作......无论如何,这不是解决该问题的重点。 问题是,是否可以使用此策略访问默认方式? 有可能用另一种方式吗? 完全不可能?

您需要通过“默认值”来澄清您的意思...它是属性类型的默认值吗? 在这种情况下,对于引用类型它是null,对于值类型,它是使用默认构造函数创建的实例:

static object GetDefaultValue(PropertyInfo prop)
{
    if (prop.PropertyType.IsValueType)
        return Activator.CreateInstance(prop.PropertyType);
    return null;
}

如果您的意思是“使用DefaultValueAttribute声明的DefaultValueAttribute ”,您可以像这样检索它:

static object GetDefaultValue(PropertyInfo prop)
{
    var attributes = prop.GetCustomAttributes(typeof(DefaultValueAttribute), true);
    if (attributes.Length > 0)
    {
        var defaultAttr = (DefaultValueAttribute)attributes[0];
        return defaultAttr.Value;
    }

    // Attribute not found, fall back to default value for the type
    if (prop.PropertyType.IsValueType)
        return Activator.CreateInstance(prop.PropertyType);
    return null;
}

如果你想在构造函数中分配给属性的值,没有创建类的实例就没有办法得到它(好吧,你可以反编译代码,但这并不容易......)

如果可以访问汇编代码,我建议使用Attribute定义默认值。

否则我认为不可能。 属性默认值不是程序集元数据的一部分(默认值概念不存在,这就是DefaultValueAttribute存在的原因)所以我不确定你能否解决它创建对象的实例的问题。 它可以是任何东西:支持字段的默认值,构造函数中设置的某个值,它可以基于某些环境条件等。

更新 :我看到一些答案/评论指向创建属性类型的默认类型。 属性默认值是特定于实现的,而不是特定于类型。 在许多情况下,它们可能会重合但不一定如此。

如果在构造函数中设置了值,并且实际上无法调用构造函数,则提取值并不容易。 这是因为该值实际上嵌入在构造函数的代码中。

如果你真的很勇敢并且有很多时间在手上,你可以尝试使用像塞西尔这样的工具直接检查IL。 如果属性是简单类型(int,double,string等),那么您可以执行以下操作:

如果通过构造函数中的字段设置:

  1. 确定属性的字段名称。 您可以根据编码约定来猜测名称(不是很漂亮,但可能会根据工具的意图完成工作),或者您可以进一步检查属性getter以查看它使用的字段。 如果属性不仅仅返回值,那么即使这可能也很棘手。

  2. 检查构造函数代码并查找对该字段的引用。 如果构造函数调用其他设置默认值的方法,这可能会很复杂。

  3. 一旦找到感兴趣的字段的Stfld,请在其上方查看常量值(Ldc_I4,Ldc_R4,Ldc_R8或Ldstr。)

如果通过构造函数中的属性设置:

  1. 确定属性设置器并在代码中查找对setter的调用。

  2. 与现场情况一样,在调用之前立即检查以查看加载的常量值。

如果你真的想尝试这个,我建议首先创建各种类型的构造函数并检查ildasm中的代码,以了解代码在编译时的外观。 在一般情况下,自动确定默认值将非常困难,但对于“常见”情况可以实现,这可能足以满足您的需要。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM