Да, важно, если Ваш объект будет использоваться в качестве ключа в словаре, или HashSet
, и т.д. - так как это используется (в отсутствие пользовательского IEqualityComparer
) к объектам группы в блоки. Если хэш-код для двух объектов не соответствует, они, май никогда не считают равным (Equals
, никогда не будет просто называться).
GetHashCode()
метод должен отразиться Equals
логика; правила:
Equals(...) == true
) тогда, они должны возвращать то же значение для GetHashCode()
GetHashCode()
равно, не необходимо для них быть тем же; это - коллизия, и Equals
будет назван, чтобы видеть, является ли это подлинное равенство или нет. В этом случае, это похоже" return FooId;
", подходящее GetHashCode()
реализация. При тестировании нескольких свойств распространено объединить их использующий код как ниже, уменьшить диагональные коллизии (т.е. так, чтобы new Foo(3,5)
имел различный хэш-код к [1 113]):
unchecked // only needed if you're compiling with arithmetic checks enabled
{ // (the default compiler behaviour is *disabled*, so most folks won't need this)
int hash = 13;
hash = (hash * 7) + field1.GetHashCode();
hash = (hash * 7) + field2.GetHashCode();
...
return hash;
}
, О - для удобства, Вы могли бы также рассмотреть обеспечение ==
и !=
операторы при переопределении Equals
и GetHashCode
.
демонстрация А того, что происходит, когда Вы понимаете это превратно, здесь .
Команда BCL провела серию из трех частей, посвященных тому, почему был сделан этот выбор и каковы обходные пути. Если вы еще не читали это, я предлагаю вам сделать это, поскольку это отличный источник информации по этому вопросу
Это ограничение должно быть довольно легко обойти с помощью небольшого вызова платформы, если ваше программное обеспечение имеет необходимые разрешения:
[DllImport("kernel32.dll", SetLastError = true)]
static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess,
uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,
uint dwFlagsAndAttributes, IntPtr hTemplateFile);
// Must close/dispose handle separately from FileStream since it's not owned by
// that object when passed to constructor.
using (SafeFileHandle h = CreateFile(longUncPath, GENERIC_WRITE, 0, IntPtr.Zero,
OPEN_EXISTING, 0, IntPtr.Zero))
{
using (var fs = new FileStream(h, FileAccess.Read))
{
// operations with FileStream object
}
}
Хорошо, попробую еще раз. Достижение оптимального количества лени в F # оказывается немного сложным ... С другой стороны, это несколько более функционально, чем моя последняя попытка, поскольку в нем не используются никакие ячейки ссылок.