이 질문에 정말 답변하지는 않지만 (미안 해요!), 여기에있는 질문에 도움을주기위한 프로젝트라고 생각합니다. 나는이 물건을 조금 뒤로 썼다. 그러나 그 이후로 아무것도하지 않고 있었다.
프로젝트는 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을 사용할 수 있다고 생각하지만 당시에는 영감을 얻지 못했습니다.)
이것은 꽤 간단한 생각이지만, 전에는 그것을 보지 못했습니다.
이제 코드 일을 잃어 버렸습니다 (코드 조각에 대한 기사 작성, 일부 코드 문서화 등 포함).하지만 느낀다면 그렇게 할 수 있습니다. 그것은 관심의 대상이 될 것입니다.
(코드 플렉스 사이트에는 다운로드 가능한 패키지가 없으므로 원본에 가서 원하는 코드 인 f # (모든 테스트 코드가 C#이지만)로 작성되었습니다. 배우기.)
어쨌든, 여기에 내 테스트 사례의 일부 샘플 C# 예제가 있습니다.
// --------------------------------------------------------------------
// USING MY ESSENCE LIBRARY:
// --------------------------------------------------------------------
[EssenceClass(UseIn = EssenceFunctions.All)]
public class TestEssence : IEquatable<TestEssence>, IComparable<TestEssence>
{
[Essence(Order=0, Format="i={0},")] public int MyInt { get; set; }
[Essence(Order=1, Format="s={0},")] public string MyString { get; set; }
[Essence(Order=2, Format="d={0:yyyy-MM-dd}")] public DateTime MyDateTime { get; set; }
public override int GetHashCode() { return Essence<TestEssence>.GetHashCodeStatic(this); }
public override string ToString() { return Essence<TestEssence>.ToStringStatic(this); }
public int CompareTo(TestEssence other) { return Essence<TestEssence>.CompareToStatic(this, other); }
public static bool operator ==(TestEssence lhs, TestEssence rhs) { return Essence<TestEssence>.EqualsStatic(lhs, rhs); }
public override bool Equals(object obj) { return this == (TestEssence)obj; }
public bool Equals(TestEssence other) { return this == other; }
public static bool operator !=(TestEssence lhs, TestEssence rhs) { return !(lhs == rhs); }
}
// --------------------------------------------------------------------
// 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;
}
public static bool operator ==(TestManual lhs, TestManual rhs)
{
if (ReferenceEquals(lhs, null))
{
if (ReferenceEquals(rhs, null))
return true;
return false;
}
if (ReferenceEquals(rhs, null))
return false;
if (ReferenceEquals(lhs, rhs))
return true;
if (typeof(TestManual) != rhs.GetType())
return false;
return lhs.MyInt == rhs.MyInt
&& lhs.MyString == rhs.MyString
&& lhs.MyDateTime == rhs.MyDateTime;
}
public override bool Equals(object obj) { return this == obj as TestManual; }
public bool Equals(TestManual other) { return this == other; }
public static bool operator !=(TestManual lhs, TestManual rhs) { return !(lhs == rhs); }
public override string ToString()
{
if (MyString == null)
return string.Format("i={0},d={1:yyyy-MM-dd}", MyInt, MyDateTime);
return string.Format("i={0},s={1},d={2:yyyy-MM-dd}", MyInt, MyString, MyDateTime);
}
public int CompareTo(TestManual other)
{
if (other == null)
return 1;
if (ReferenceEquals(this, other))
return 0;
int result = 0;
result = MyInt.CompareTo(other.MyInt);
if (result != 0) return result;
result = MyString.CompareTo(other.MyString);
if (result != 0) return result;
result = MyDateTime.CompareTo(other.MyDateTime);
if (result != 0) return result;
return result;
}
}
// --------------------------------------------------------------------
// --------------------------------------------------------------------
// ALTERNATIVE USAGE
// --------------------------------------------------------------------
// --------------------------------------------------------------------
class Simple
{
public Simple(int value) { Value1 = value; }
public Simple(int value1, int value2) { Value1 = value1; Value2 = value2; }
public readonly int Value1;
public readonly int Value2;
}
[Test]
public void TestReverseForwardString()
{
var _11 = new Simple(1, 1);
var _12 = new Simple(1, 2);
var _21 = new Simple(2, 1);
var _22 = new Simple(2, 2);
var items = new[] { _11, _12, _21, _22 };
var reverseComparer = Essence<Simple>.CreateComparer("-Value1", "Value2");
Array.Sort(items, reverseComparer);
Assert.AreSame(_21, items[0]);
Assert.AreSame(_22, items[1]);
Assert.AreSame(_11, items[2]);
Assert.AreSame(_12, items[3]);
}
[Test]
public void TestReverseForwardLambda()
{
var _11 = new Simple(1, 1);
var _12 = new Simple(1, 2);
var _21 = new Simple(2, 1);
var _22 = new Simple(2, 2);
var items = new[] { _11, _12, _21, _22 };
var reverseComparer = Essence<Simple>.CreateComparer(x => x.Action.ReverseNext, x => x.Member.Value1, x => x.Member.Value2);
Array.Sort(items, reverseComparer);
Assert.AreSame(_21, items[0]);
Assert.AreSame(_22, items[1]);
Assert.AreSame(_11, items[2]);
Assert.AreSame(_12, items[3]);
}
재미있게 보내십시오!
폴.
대답하지 않습니다. 그럼에도 불구하고 재미있는 독서. 감사. –