2012-03-03 65 views
1

我有一個類:等同於2個對象 - 每次都不同?

public class Person 
    { 
     public string name { get; set; } 
     public int age { get; set; } 
    } 

     Person p1 = new Person() { age=1, name="a" }; 
     Person p2 = new Person() { age = 1, name = "b" }; 

我要像做

p1.equals(p2) 

年齡或名字

我不加入的方式是指字典(並使用Iequatable ...)

的Equals滿足HOD犯規採取任何助手裏面......

enter image description here

是沒有辦法,我可以給他我的具體的輔助類的任何方式就像:

Dictionary<PersonForDictionary, int> dct2 = 
new Dictionary<PersonForDictionary, int>(new helperClass()); // here helperclass is a class which I gave him - and told the dictionary how to equate objects.... 

進出口尋找一個類似解決方案等同物體時。 (不在字典模式下)。

+1

你的意思是,當你第一次稱它爲名字平等時,第二次爲年齡平等,然後再爲名字等等? – Tudor 2012-03-03 18:07:01

+0

如果我把他的名字的比較對象轉移給他,所以按名字,年齡相同...(如果我把他比作年齡的對象,所以年齡...) – 2012-03-03 18:08:32

回答

3

可能是,可能也喜歡做的IComparable不同的實現。 例如:

public class Person 
{ 
    public string name { get; set; } 
    public int age { get; set; } 

    pulbic int ComparePerson(Person person, IComparable comparer) 
    { 
    return comparer.Compare(this, person); 
    } 
} 

實施後不同類別:

public class PersonNameComparer : IComparer 
{ 
} 

或其他

public class PersonAgeComparer : IComparer 
{ 
} 

和內部使用它:

Person p1 = new Person() { age=1, name="a" }; 
Person p2 = new Person() { age = 1, name = "b" }; 

p1.Compare(p2, new PersonNameComparer()); 
p1.Compare(p2, new PersonAgeComparer()); 
+1

那麼它將不得不是一個'IEqualityComparer',儘管(最好是強類型)。 – 2012-03-03 18:29:22

+0

@Jeff Mercado。是的,答案只是爲了提供行爲注入的可能性。 +1 – Tigran 2012-03-03 18:31:35

+0

很好的解決方法! – 2012-03-03 18:33:15

0

最好的選擇是爲你想要做的比較類型添加一個方法。

public class Person 
{ 
    public string Name { get; set; } 
    public int Age { get; set; } 

    public bool SameAge(Person otherPerson) 
    { 
     return Age == otherPerson.Age; 
    } 

    public bool SameName(Person otherPerson) 
    { 
     return Name == otherPerson.Name; 
    } 
} 
0

你爲什麼不創建兩個比較器,一個按名稱和另一個按年齡,並按需要傳遞它?像這樣做:

class NameComparer: IComparer<Person> 
{ 
    public int Compare(Person x, Person y) 
    { 
     if(x.Name < y.Name) 
      return -1; 
     else if (x.Name == y.Name) 
      return 0; 
     else 
      return 1; 
    } 
} 

對年齡做同樣的事情。

+0

這正是我想要做的。你能告訴我如何? – 2012-03-03 18:21:03

1

所以,你要創建一個比較如此喲你可以做你自定義的比較?那麼最終你會想要創建一個類來實現你想要做的每個比較的接口IEqualityComparer<T>。或者你可以創建一個類,可以投射你的對象爲要比較的字段...

你可以做這樣的事情:

var lengthComparer = ProjectionEqualityComparer.Create((String s) => s.Length); 
Console.WriteLine(lengthComparer.Equals("foo", "bar")); // true 
Console.WriteLine(lengthComparer.Equals("biz", "baaz")); // false 

var nameComparer = ProjectionEqualityComparer.Create((Person p) => p.Name); 
var dict = new Dictionary<Person, int>(nameComparer); 

和實際的實現:

// helper class to make creating the comparers easier 
public static class ProjectionEqualityComparer 
{ 
    public static ProjectionEqualityComparer<TSource, TKey> Create<TSource, TKey>(Func<TSource, TKey> selector, IEqualityComparer<TKey> comparer = null) 
    { 
     return new ProjectionEqualityComparer<TSource, TKey>(selector, comparer); 
    } 
} 

// the actual comparer 
public class ProjectionEqualityComparer<TSource, TKey> : EqualityComparer<TSource> 
{ 
    private Func<TSource, TKey> selector; 
    private IEqualityComparer<TKey> comparer; 
    public ProjectionEqualityComparer(Func<TSource, TKey> selector, IEqualityComparer<TKey> comparer = null) 
    { 
     if (selector == null) throw new ArgumentNullException("selector"); 
     this.selector = selector; 
     this.comparer = comparer ?? EqualityComparer<TKey>.Default; 
    } 

    public override bool Equals(TSource x, TSource y) 
    { 
     var xKey = selector(x); 
     var yKey = selector(y); 
     return comparer.Equals(xKey, yKey); 
    } 

    public override int GetHashCode(TSource source) 
    { 
     var key = selector(source); 
     return key.GetHashCode(); 
    } 
} 
相關問題