簡體   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