等同2个对象 - 每次都不同?

时间:2012-03-03 18:04:10

标签: c# .net-4.0

我有一个班级:

  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方法不会在其中包含任何Helper ......

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....

我在等同物时寻找类似的解决方案。 (不是字典模式)。

4 个答案:

答案 0 :(得分: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 :(得分: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();
    }
}

答案 2 :(得分: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;
    }
}

答案 3 :(得分: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;
    }
}

年龄相同。