我有一个实现IEquatable <>的类A,使用它的字段(比如Ab和Ac)来实现/重写Equals()并覆盖GetHashCode(),并且99%的时候一切正常.A类是层次结构(B类,C类)的一部分,它们都从接口D继承; 它们都可以一起存储在字典中,因此当它们都带有自己的默认Equals()/ GetHashCode()时很方便.
然而,在构建AI时,有时需要做一些工作来获得Ab和Ac的值; 当发生这种情况时,我想存储对正在构建的实例的引用.在这种情况下,我不想使用A提供的默认Equals()/ GetHashCode()覆盖.因此,我正在考虑实现一个ReferenceEqualityComparer,这意味着强制使用Object的Equals()/ GetHashCode() :
private class ReferenceEqualityComparer<T> : IEqualityComparer<T>
{
#region IEqualityComparer<T> Members
public bool Equals(T x, T y)
{
return System.Object.ReferenceEquals(x, y);
}
public int GetHashCode(T obj)
{
// what goes here? I want to do something like System.Object.GetHashCode(obj);
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
问题是,由于A重写了Object.GetHashCode(),我如何(在A之外)调用Object.GetHashCode()作为A的实例?
当然,一种方法是A不实现IEquatable <>并且始终为我创建的任何字典提供IEqualityComparer <>,但我希望得到不同的答案.
谢谢
如果我有一个类型的对象MyBull和一个List<MyBull> orig:
// Just an example
MyBull x = getMeTheObjectWithIdFromDB(9);
orig.add(x);
// Again same? data object
MyBull y = getMeTheObjectWithIdFromDB(9);
Run Code Online (Sandbox Code Playgroud)
为什么这是假的呢?
// This is false, even though all the properties
// of x and y are the same.
orig.Contains<MyBull>(y);
Run Code Online (Sandbox Code Playgroud) 我想List通过使用IEqualityComparer接口从C# 中获取不同的项目。但我不知道GetHashCode. 我已经实现了GetHashCode和Equals方法。以及如何调用Equals方法从具有用户定义数据类型的列表中获取不同的项目。
我正在编写实现IEqualityComparer的这个整洁的类,因此我可以将任何匿名类型传递给它(或实际上任何具有属性的类型),它将通过比较类型的属性值自动比较类型.
public class CompareProperty<T> : IEqualityComparer<T>
{
private Type type;
private PropertyInfo propInfo;
private string _fieldName;
public string fieldName
{
get;
set;
}
public CompareProperty(string fieldName)
{
this.fieldName = fieldName;
}
public bool Equals<T>(T x, T y)
{
if (this.type == null)
{
type = x.GetType();
propInfo = type.GetProperty(fieldName);
}
object objX = propInfo.GetValue(x, null);
object objY = propInfo.GetValue(y, null);
return objX.ToString() == objY.ToString();
}
}
Run Code Online (Sandbox Code Playgroud)
我认为这是一个很好的小助手功能,我可以多次使用.
为了使用它,我必须这样做:
var t = typeof(CompareProperty<>);
var g = t.MakeGenericType(infoType.GetType());
var c = g.GetConstructor(new …Run Code Online (Sandbox Code Playgroud) 如果我有两个类型为T的集合,以及一个比较其属性子集的IEqualityComparer,那么Intersect或Union的结果元素来自哪个集合?
我到目前为止进行的测试表明如下:
我知道这不应该是一个问题,因为(根据定义)我应该将结果对象视为相等.我刚刚想到,使用带有自定义比较器的Union可能比等效的Join更整洁 - 尽管如果上述假设得到保证,这只适用.
class DummyComparer : IEqualityComparer<Dummy>
{
public bool Equals(Dummy x, Dummy y)
{
return x.ID == y.ID;
}
public int GetHashCode(Dummy obj)
{
return obj.ID.GetHashCode();
}
}
class Dummy
{
public int ID { get; set; }
public string Name { get; set; }
}
[Test]
public void UnionTest()
{
var comparer = new DummyComparer();
var d1 = new Dummy { ID = 0, Name = "test0" };
var d2 = new Dummy …Run Code Online (Sandbox Code Playgroud) 我有两个相同类型的列表.
一个列表是从文件加载并转换为正确类型的反序列化json对象.
另一个是由相同类型的对象创建的列表.
当我这样做时,List2.Except(List1)我希望看到一切都List2没有List1
在这种情况下,List2将拥有所有的东西,List1而不是更多,所以我希望看到Enumerable<T>大小为0的结果,但我只是看到整个,List2好像比较从未发生过.
IEnumerable<Review> newReviews = reviews.Except(savedRvReviews, new ReviewComparer());
Run Code Online (Sandbox Code Playgroud)
我也试过使用EqualityComparer下面的代码:
public class ReviewComparer : IEqualityComparer<Review>
{
public bool Equals(Review x, Review y)
{
return x.ReviewID == y.ReviewID;
}
public int GetHashCode(Review rv)
{
return EqualityComparer<Review>.Default.GetHashCode(rv);
}
}
Run Code Online (Sandbox Code Playgroud)
并得到了相同的结果.
通过LINQ查询迭代List2和搜索List1,我得到0的预期结果.
foreach (Review s in reviews)
{
var m = from k in savedRvReviews
where k.ReviewID == s.ReviewID
select k;
if …Run Code Online (Sandbox Code Playgroud) 我编写了一个代码,该代码基本上比较了C#中的两个列表。第一个列表包含以下属性:
第一个列表缺少TotalViews的值,因此我从第二个列表中为它们分配了这些道具:
代码如下:
foreach (var item in parsedMerchantData)
{
var itemInB = HitCountItemIDS.FirstOrDefault(x => x.ItemID == item.ItemID);
if (itemInB != null)
{
if (itemInB.HitCount != -1)
{
item.TotalViews = itemInB.HitCount;
}
else
{
item.TotalViews = 0;
}
}
}
Run Code Online (Sandbox Code Playgroud)
是否有任何更有效的方式使用LINQ编写此代码或实现自定义比较器,该自定义比较器在有时包含100000个项目的较大列表上工作更快?
我刚刚意识到我编写了我希望无效的代码(关于语法),但编译器接受了.
为了简洁起见,我重新创建了一个例子.给定类型:
private class MyType
{
}
Run Code Online (Sandbox Code Playgroud)
然后,我可以比较的一个实例MyType到IEnumerable<MyType>:
var myCollection = new List<MyType> { };
var test = new MyType() == (IEnumerable<MyType>)myCollection;
Run Code Online (Sandbox Code Playgroud)
我很惊讶我能比较两种不同类型的物体.更有意思(至少对我有趣),如果我删除了演员,IEnumerable我无法比较它.为什么会这样?一个List工具,IEnumerable所以假设某种平等比较器在某个地方,我缺少(可能是错误的),为什么这也不可用List?
我有一个叫做的课
MyClass
Run Code Online (Sandbox Code Playgroud)
这个类继承IEquatable并实现等于我需要它的方式.(含义:当我在代码中单独比较两个MyClass tyupe对象时,它可以工作)
然后我创建两个List:
var ListA = new List<MyClass>();
var ListB = new List<MyClass>();
// Add distinct objects that are equal to one another to
// ListA and ListB in such a way that they are not added in the same order.
Run Code Online (Sandbox Code Playgroud)
当我去比较ListA和ListB时,我应该得到真的吗?
ListA.Equals(ListB)==true; //???
Run Code Online (Sandbox Code Playgroud) 假设有这个类:
public class Foo
{
public int Id { get; set; }
public int? NullableId { get; set; }
public Foo(int id, int? nullableId)
{
Id = id;
NullableId = nullableId;
}
}
Run Code Online (Sandbox Code Playgroud)
我需要按照以下规则比较这些对象:
为了实现它,我像这样覆盖了 Equals 和 GetHashCode:
public override bool Equals(object obj)
{
var otherFoo = (Foo)obj;
var equalityCondition = Id == otherFoo.Id;
if (NullableId.HasValue && otherFoo.NullableId.HasValue)
equalityCondition &= (NullableId== otherFoo.NullableId);
return equalityCondition;
}
public override int GetHashCode()
{
var …Run Code Online (Sandbox Code Playgroud) c# ×10
list ×3
.net ×2
gethashcode ×2
iequatable ×2
linq ×2
c#-4.0 ×1
casting ×1
equality ×1
equals ×1
except ×1
generics ×1
ienumerable ×1
intersect ×1
nullable ×1
reflection ×1
types ×1
union ×1