[英]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 == secondExample
和firstExampleValue.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.