-1

指定されたインスタンスがコレクションと一致していることを確認する必要があります(どちらも不明な型です)。次のコードを検討する - たとえば未知の型の等価性の決定

public bool CheckEquality(object obj1, object obj2) 
{ 
    // Solution for Determining equality for unknown types 
} 

:(唯一の目的を理解するために)

シナリオ#1

は、メソッドをチェック表情

void Main() 
{ 
    // Employee "John" Object got from Service Layer #1 
    Object obj1 = Client1.GetObject("John"); 

    // Employee "John" Object got from Service Layer #2 
    Object obj2 = Client2.GetObject("John"); 

    bool flag = CheckEquality(obj1, obj2); // Both objects are Unknown Type 
} 

平等を持っています

public class EmpPerson 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public string Address { get; set; } 
} 

obj1new EmpPerson() { ID = 1, Name = "John", Address = "Los Angeles" };

obj2インスタンスを保持しているインスタンスを保持new EmpPerson() { ID = 1, Name = "John", Address = "Los Angeles" };

シナリオ#2

obj1"John Smith"を保持します。

obj2は、値"John Smith"を保持します。

シナリオ#3

obj1は値"John Smith"を保持しています。

obj2インスタンスを保持new EmpPerson() { ID = 1, Name = "John", Address = "Los Angeles" };

シナリオ#4

obj1new UnknownTypeA()を保持します。

obj2は、値new UnknownTypeX()を保持します。

私は両方のオブジェクトが同一であることを確認する必要があります。

私を親切にしてください。不明な型の等価性をチェックする方法。

+5

他にはどのような種類が関係しているのでしょうか?以前の別の質問のコメントに従って、型はフィールドによって公開されていない「隠れた」状態になっている可能性がありますか?それはコレクションを含むことができますか?その状態を隠す型の例として、 'Random'プロパティを含むことができますか?循環参照を含めることはできますか?これは一般的には可能ではありませんが、関係するタイプを制約すると、それを反映させることができます。 (循環参照については注意が必要です...) –

+0

@JonSkeet - 答えを教えてください... –

+1

シナリオ#2では、 'obj1'と' obj2'は単純に文字列であるか、 EmpPerson'だけど名前は知ってる? –

答えて

1

OK私はあなたが平等で何を意味するのか、すべての

まず、...あなたがここに欠けているいくつかのポイントがあると思いますか?

2つのオブジェクトが同じ参照を保持している場合、オブジェクトは同じですか? 共通のプロパティを持つ場合は同じですか? いつですか?

あなたが知らないオブジェクトの等価性をチェックする必要があるのはなぜですか?

オブジェクトの種類がわからない場合は、それらのオブジェクトが等しいと言う点は何ですか?あなたもそれらを使用することはできません...

あなたのオブジェクトの種類を知っている場合は、それらを比較する方法を知っています。

シナリオケース#4のを追加しました。タイプがわからないときに、異なるタイプの2つのオブジェクトを比較する理由は何ですか?

OOPでは、我々は通常、共通の保持インターフェースを作成する理由

は、だから、だ...それは意味がありませんので、あなたはリンゴと梨を比較することはできません、異なる型のオブジェクトを比較することはできませんオブジェクト型を別の型に変換するメソッドを作成する必要があります。

私がここで示した解決策は、オブジェクトの実装を制御できることを意味します。

Equals()メソッド(Objectから継承)をオーバーロードします。

public class EmpPerson 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public string Address { get; set; } 

    public override bool Equals(object obj) 
    { 
     EmpPerson cmp = (EmpPerson)obj; 
     return ID.Equals(cmp.ID); 
    } 
} 

そして、あなたはそれらを比較する必要があるとき:

obj1.Equals(obj2); 

しかし、これは、オブジェクトが同じタイプ、どんなタイプである必要が制限をもたらします。

NB:エラーチェックはここで実装されていない、あなたがそれを行う必要があります...

+0

私はサービスからオブジェクトを取得しています。私は、それがどのような種類のオブジェクトであるかはわかりません。それが問題です。 –

+0

@IRPunch OKオブジェクトのコードを書いたと思いました。あなたは何をしたいですか?彼らが何であるか分からない2つのことを比較することは可能ですか? –

+0

シナリオ#4で見てください –

1

あなたは深い反射を経由してオブジェクトの比較を実行するために使用することができるCompare-Net-Objects deep equals libraryをチェックアウトすることができます。

1

このコードは、型およびパブリックフィールドリストによって償還オブジェクトなしで比較されます。それは、償還とプロパティを追加することによって改善することができます。しかし、それはすべての場合のために、ソルトンではありません。

bool AreEquals(object a, object b) 
{ 
    if (a == null && b == null) return true; 
    if (a == null || b == null) return false;  

    var typeA = a.GetType(); 
    var typeB = b.GetType(); 

    if (typeA.Equals(typeB)) return a.Equals(b); 

    var fieldsA = typeA.GetFields().Where(field => field.IsPublic).ToArray(); 
    var fieldsB = typeB.GetFields().Where(field => field.IsPublic).ToArray(); 

    if (fieldsA.Length != fieldsB.Length) return false; 

    foreach(var field in fieldsA) 
    { 
    var other = fieldsB.FirstOrDefault(f => f.FieldType.Equals(field.FieldType) && f.Name.Equals(field.Name)); 
    if (other == null) return false; 

    if (!field.GetValue(a).Equals(other.GetValue(b))) return false; 
    } 

    return true; 
} 
+0

私はそれが動作するかもしれないと思う。 –

0

もう1つの可能性は、オブジェクトをシリアル化し、シリアル化された出力を比較することです。

Binary serialization for deep object comparison

これは、バイナリまたはXML、または何のいずれかになります。これは非常に汎用的なので、すぐに使用できるユーティリティを使用してシリアル化の動作に影響を与えることができます。