使用C#,我想找到一种方法来实现类似于依赖于两个关键对象的字典.
我有一个对象和一个字符串.对于这两个值,我想分配一个double值.那么我应该使用什么结构?或者我该如何实现这样的结构?
在这篇MSDN文章 http://msdn.microsoft.com/en-us/library/ms132123.aspx中, 它讨论了Class Equalitycomparer并有一个例子.在这个关于比较它的例子中它有这个类 -
class BoxSameDimensions : EqualityComparer<Box>
{
public override bool Equals(Box b1, Box b2)
{
if (b1.Height == b2.Height & b1.Length == b2.Length
& b1.Width == b2.Width)
{
return true;
}
else
{
return false;
}
}
public override int GetHashCode(Box bx)
{
int hCode = bx.Height ^ bx.Length ^ bx.Width;
return hCode.GetHashCode();
}
}
Run Code Online (Sandbox Code Playgroud)
我不明白行hCode = bx.Height ^ bx.Length ^ bx.Width;
有人可以解释一下吗?为什么xor?
命名空间中的IEqualityComparerSystem.Collections.Generic具有以下方法:
bool Equals(T x, T y);
int GetHashCode(T obj);
Run Code Online (Sandbox Code Playgroud)
由于此接口用于检查对象的相等性,因此第一种方法Equals是有意义的.但为什么我们也需要实施GetHashCode呢?为什么它首先存在于界面中?什么时候需要,为什么?
我在命名空间中使用它和Enumerable.Distinct()方法System.Linq,我很惊讶地发现它甚至GetHashCode()被调用了Equals().为什么?Distinct工作怎么样?
StringComparer.InvariantCultureIgnoreCase Equals为""vs"\ 0"返回true,但GetHashCode为这两个字符串返回不同的值.这是一个错误吗?
var sc = StringComparer.InvariantCultureIgnoreCase;
string s1 = "";
string s2 = "\0";
Console.WriteLine( sc.Equals(s1, s2) );
Console.WriteLine( sc.GetHashCode(s1) );
Console.WriteLine( sc.GetHashCode(s2) );
Run Code Online (Sandbox Code Playgroud)
回报
True
0
-1644535362
Run Code Online (Sandbox Code Playgroud)
我认为GetHashCode应该为'equal'字符串返回相同的值,所以这是一个错误吗?
鉴于以下课程:
public class WeekOfYear : IEquatable<WeekOfYear>, IComparable<WeekOfYear>
{
private readonly DateTime dateTime;
private readonly DayOfWeek firstDayOfWeek;
public WeekOfYear(DateTime dateTime)
: this(dateTime, DayOfWeek.Sunday)
{
}
public WeekOfYear(DateTime dateTime, DayOfWeek firstDayOfWeek)
{
this.dateTime = dateTime;
this.firstDayOfWeek = firstDayOfWeek;
}
public int Year
{
get
{
return dateTime.Year;
}
}
public int Week
{
get
{
return CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, firstDayOfWeek);
}
}
public bool Equals(WeekOfYear other)
{
return Year == other.Year && Week == other.Week;
}
public int CompareTo(WeekOfYear other)
{
if (Year …Run Code Online (Sandbox Code Playgroud) 我发现很多帖子都解释说应该总是在NHibernate实体类上重写Equals/GetHashCode.如果我不使用套装,这真的有必要吗?
我根本找不到一个示例,其中显示缺少Equals/GetHashCode会导致意外和错误的行为.没有它们,一切似乎都很完美.这真是奇怪,每个人都说这是必要的,但没有人能提供一个样本,说明为什么需要这样做.
我有一个名为'x'的类,它覆盖Equals(),如下所示:
public override bool Equals(object obj)
{
if(obj is x)
{
return ((obj as x).key == this.key);
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
当以下扩展方法尝试使用上面的覆盖进行比较时,不会使用Equals():
public static bool Contains(this HashSet<x> set, char key)
{
x SearchKey = new x(key);
return set.Contains(SearchKey);
}
Run Code Online (Sandbox Code Playgroud)
只有当我修改extensio方法中的第一行时,我才会得到预期的行为,如下所示:
x SearchKey = new x(key);
Run Code Online (Sandbox Code Playgroud)
你能解释一下这种行为吗?
我曾经预料到,Equals()将被调用x本身的实例,因为它是Object的一个子集.我错过了什么?
我注意到EF的DbSet.Add()非常慢.一个小小的谷歌搜索出现了一个SO答案,承诺高达180倍的性能提升:
但是,我不明白如何IEquatable<T>按照答案中的建议实施.
根据MSDN,如果我实现IEquatable<T>,我也应该覆盖Equals()和GetHashCode().
和许多POCO一样,我的对象是可变的.在提交到database(SaveChanges())之前,新对象的Id为0. 保存对象后,Id作为实现IEquatable,Equals()和GetHashCode()的理想基础.
在哈希代码中包含任何可变属性是不明智的,因为根据MSDN
如果两个对象比较相等,则每个对象的GetHashCode方法必须返回相同的值
我应该实现IEquatable<T>逐个属性比较(例如this.FirstName == other.FirstName)并且不重写Equals()和GetHashCode()吗?
鉴于我的POCO用于EntityFramework上下文,是否应该特别注意Id字段?
我不知道这里的问题是什么,
我有一个HashSet<object>名为_itemsToProcess的人.
最终在我的代码中(没有多头)我想从hashset中删除项目
_itemsToProcess.Remove(item);
Run Code Online (Sandbox Code Playgroud)
这不起作用.我也试过了
_itemsToProcess.RemoveWhere(i=>i.Equals(item));
Run Code Online (Sandbox Code Playgroud)
嗯,它看起来微不足道,但我可以保证,项目在_itemsToProcess内.我通过调试检查了
_itemsToProcess.Any(item.Equals) // Returns true
_itemsToProcess.Contains(item) // Returns false
item.GetHashcode() == _itemsToProcess.First().GetHashcode() // returns true aswell.
Run Code Online (Sandbox Code Playgroud)
该项目没有实现ICompareable,也没有IEquatable,所以我在这里想法.
示例(简化了很多,因为这是一件大事)
readonly _itemsToProcess = new HashSet<object>();
void getItems()
{
foreach(object o in getObjects())
if(meetsCriteria(o)) _itemsToProcess.Add(o);
}
void processItems()
{
if(_itemsToProcess.Count> 0)
{
foreach(object item in _itemsToProcess.Where(criteria).ToArray())
processItem(item);
}
}
// This gets called in different ways
void processItem(object item)
{
... do stuff
if(succes)
_itemsToProcess.Remove(item);
}
Run Code Online (Sandbox Code Playgroud)
所以重新解决问题
var compare = _itemsToProcess.First();
compare.GetHashcode() == item.GerHashcode() // …Run Code Online (Sandbox Code Playgroud) 说我有一个包含这样的对象的列表:
public class Person
{
private string _name;
private string _id;
private int _age;
public Person
{
}
// Accessors
}
public class ManipulatePerson
{
Person person = new Person();
List<Person> personList = new List<Person>;
// Assign values
private void PopulateList();
{
// Loop
personList.Add(person);
// Check if every Person has a unique ID
}
}
Run Code Online (Sandbox Code Playgroud)
我想检查每个人都有一个唯一的ID.我想返回一个布尔值true/false,具体取决于ID是否唯一.这是我用LINQ可以实现的吗?