2012-03-03 63 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(); 
    } 
} 
相关问题