C# 等同于2个对象-每次不同?

C# 等同于2个对象-每次不同?,c#,.net-4.0,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

我有一门课:

  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方法不接受任何帮助程序

我有没有办法把我的特定助手类发送给他,就像:

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

我正在寻找一个类似的解决方案时,相等的对象。不在字典模式下。

最好的选择是只为要执行的比较类型添加一个方法

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;
    }
}

最好的选择是只为要执行的比较类型添加一个方法

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;
    }
}

为什么不创建两个比较器,一个按名称,另一个按年龄,并根据需要传递它呢?这样做:

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;
    }
}
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);

对年龄也一样。

为什么不创建两个比较器,一个按名称,另一个按年龄,并根据需要传递它呢?这样做:

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;
    }
}
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);

对年龄也一样。

可能是,也可能是让不同的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 ());

可能是,也可能是使不同的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 ());

那么您想创建一个比较器,以便进行自定义比较?最终,您需要创建一个类来实现IEqualityComparer接口,用于您想要进行的每个比较。或者,您可以创建一个类,将对象投影到要比较的字段中

你可以这样做:

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;
    }
}
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();
    }
}

那么您想创建一个比较器,以便进行自定义比较?最终,您需要创建一个类来实现IEqualityComparer接口,用于您想要进行的每个比较。或者,您可以创建一个类,将对象投影到要比较的字段中

你可以这样做:

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;
    }
}
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();
    }
}

你的意思是当你第一次调用它时,它应该检查名称是否相等,第二次检查年龄是否相等,然后再次检查名称等等?如果我向他传递一个名为的比较器对象,那么按名称执行,年龄也一样。。。如果我给他一个比较对象的年龄,那么按年龄来做…你的意思是当你第一次调用它时,它应该检查名称是否相等,第二次是否相等,然后再次检查名称等?如果我给他一个比较对象的名称,那么按名称来做,年龄也一样。。。如果我给他一个比较对象来表示年龄,那么按年龄来做……这正是我想要做的。你能告诉我怎么做吗?那正是我想做的。你能告诉我怎么做吗?虽然最好是强类型的,但它必须是一个IEqualityComparer。@Jeff Mercado。是的,答案只是提供了一个关于行为注射可能性的想法+1它必须是一个IEqualityComparer,但最好是强类型的。@Jeff Mercado。是的,答案只是提供了一个关于行为注射可能性的想法+1.