Некоторое время назад я написал кое-что, что вы могли бы решить вашу проблему ... (И на самом деле, возможно, это можно было бы улучшить, включив в себя семена, которые у вас есть ...)
В любом случае, проект называется Essence (http://essence.codeplex.com/), и он использует библиотеки System.Linq.Expression для генерации (на основе атрибутов) стандартных представлений Equals / GetHashCode / CompareTo / ToString, а также возможность создавать классы IEqualityComparer и IComparer на основе списка аргументов. (У меня также есть некоторые дополнительные идеи, но я хотел бы получить обратную связь от сообщества, прежде чем продолжать слишком много дальше.)
(Это означает, что он почти такой же быстрый, как и рукописный - основной, где это не так, является CompareTo (); потому что в Linq.Expressions нет понятия переменной в версии 3.5 - поэтому вы должны вызывать CompareTo () для базового объекта дважды, когда вы не получаете совпадение. Использование расширений DLR для Linq.Expressions решает эту проблему. Полагаю, я мог бы использовать emit il, но меня это не вдохновило в то время.)
Это довольно простая идея, но я не видел, чтобы это было сделано раньше.
Теперь дело в том, что я как бы потерял интерес к его полировке (что включало бы написание статьи для codeproject, документирование некоторого кода и т. П.), Но я мог бы убедить вас сделать это, если вы чувствуете это будет что-то интересное.
(На сайте codeplex нет загружаемого пакета; просто перейдите к исходному коду и возьмите его - о, он написан на f # (хотя весь тестовый код на c #), так как это было тем, что мне было интересно изучать .)
В любом случае, вот пример c # из теста в проекте:
// --------------------------------------------------------------------
// USING THE ESSENCE LIBRARY:
// --------------------------------------------------------------------
[EssenceClass(UseIn = EssenceFunctions.All)]
public class TestEssence : IEquatable<TestEssence>, IComparable<TestEssence>
{
[Essence(Order=0] public int MyInt { get; set; }
[Essence(Order=1] public string MyString { get; set; }
[Essence(Order=2] public DateTime MyDateTime { get; set; }
public override int GetHashCode() { return Essence<TestEssence>.GetHashCodeStatic(this); }
...
}
// --------------------------------------------------------------------
// EQUIVALENT HAND WRITTEN CODE:
// --------------------------------------------------------------------
public class TestManual
{
public int MyInt;
public string MyString;
public DateTime MyDateTime;
public override int GetHashCode()
{
var x = MyInt.GetHashCode();
x *= Essence<TestEssence>.HashCodeMultiplier;
x ^= (MyString == null) ? 0 : MyString.GetHashCode();
x *= Essence<TestEssence>.HashCodeMultiplier;
x ^= MyDateTime.GetHashCode();
return x;
}
...
}
Во всяком случае, проект, если кто-то считает, что стоит, нуждается в доработке, но идеи есть ...