簡體   English   中英

將屬性值轉換回原始類型以與反射進行比較

[英]Cast property values back to original types for comparison with reflection

我目前正在嘗試使用反射與數據合同進行比較。

數據協定代表虛擬機的配置。 它們都是相同的類類型。 設置新配置時,我試圖記錄配置中的所有更改。 但是,數據合同具有大量成員。 手動執行該操作很繁瑣,並且無法容納以后添加的新數據成員。

我嘗試使用反射來做到這一點。 我設法獲取了數據成員的值,但是根據實際類型,比較它們會有所不同。

被比較的一些成員是:

  • IEnumerable<Subnets>

  • IEnumerable<IP Address>

  • X509Certificates

  • Enums

還有一些

我試圖找到一種將屬性轉換為實際類的方法,但是到目前為止,我發現的所有方法都無法正常工作。

這是到目前為止我所做的反思的一個例子。

ExampleClass firstExample = new ExampleClass("a", 1);
ExampleClass secondExample = new ExampleClass("a", 2);
List<string> exampleList = new List<string>()
{
    "a",
    "b"
};

firstExample.ValueThree = exampleList;
secondExample.ValueThree = exampleList;

firstExample.FourthValue = new List<string>()
{
    "c",
    "d"
};

secondExample.FourthValue = new List<string>()
{
    "c",
    "d"
};

Type exampleType = firstExample.GetType();

foreach (PropertyInfo item in exampleType.GetProperties())
{
    var firstExampleValue = item.GetValue(firstExample);
    var secondExampleValue = item.GetValue(secondExample);
    string propName = item.Name;

    bool areEqual = firstExampleValue.Equals(secondExampleValue);

    Console.WriteLine(propName);
    Console.WriteLine(string.Format("\nFirst Value : {0}\nSecond Value : {1}", firstExampleValue, secondExampleValue));
    Console.WriteLine(string.Format("Values are equal : {0}\n\n", areEqual));
}

是否有一種實用的方法可以將它們轉換為數據協定定義的實際類? 我研究了Convert.ChangeType但是發現這對於大部分成員來說都不起作用,因為它們不是IConvertable

謝謝,

埃德溫

這與獲取基礎類型無關。 這就是所謂的“相等”。

在.NET中,每種類型都從object繼承,從而繼承Object.Equals() 但是對於引用類型, Object.Equals()將僅比較兩個對象是否是完全相同的對象 ,而不是它們的內容是否相等。

例如, new List<string>() == new List<string>()始終為false

這就是為什么firstExample == secondExamplefirstExampleValue.Equals(secondExampleValue)始終為false

但是,類可以覆蓋Equals方法。 例如, String重寫Equals()以便比較兩者的內容。

在這種情況下,如果ExampleClass是您控制的類,則可以重寫Equals並告訴它比較每個屬性的內容(以及每個List的內容)以確定它們是否相等。 完成此操作后,您只需編寫firstExample == secondExample ,它為true

Object.Equals()的文檔實際上有一個簡單的示例: https : //docs.microsoft.com/zh-cn/dotnet/api/system.object.equals

更新:強制轉換為基礎類型並沒有任何好處。 即使將類型強制轉換為object ,當您進行比較時,它仍會使用基礎類型的Equals 例如,這將導致true((object)"hello") == ((object)"hello")因為它使用String.Equals而不是Object.Equals

因此,您真正的問題是知道類型是否已覆蓋Equals 您可以像這樣測試類型是否覆蓋了Equals

var type = typeof(string);
var overriddenEquals = type.GetMember("Equals").First().DeclaringType != typeof(object);

但這對於沒有覆蓋equals的類型仍然沒有幫助。 您如何比較它們?

唯一的方法就是知道將要使用的類型並專門測試那些類型(一堆if語句),並決定如何比較它們。 (對於列表,您可以測試is IEnumerable ,循環遍歷,然后測試列表內的類型)

在這種情況下,該類型是否實現IConvertible並不重要,因為您將知道該類型是什么並且可以直接將其IConvertible為它,例如:

if (obj is Subnets objSubnets) {
    //compare objSubnets to another Subnets object
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM