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.