我有一些看起來像下面的代碼。首先,我有一些域類和一些特殊的比較器。如何讓C#編譯器自動推斷出這些類型參數?
public class Fruit {
public int Calories { get; set; }
public string Name { get; set; }
}
public class FruitEqualityComparer : IEqualityComparer<Fruit> {
// ...
}
// A basket is just a group of Fruits.
public class BasketEqualityComparer : IEqualityComparer<IEnumerable<Fruit>> {
// ...
}
接下來,我有一個幫助類叫ConstraintChecker
。它有一個簡單BaseEquals
方法,該方法可以確保一些簡單的基本情況都有考慮:
public static class ConstraintChecker {
public static bool BaseEquals(T lhs, T rhs) {
bool sameObject = l == r;
bool leftNull = l == null;
bool rightNull = r == null;
return sameObject && !leftNull && !rightNull;
}
還有一個SemanticEquals
方法這僅僅是一個BaseEquals
檢查和您指定的比較器功能。
public static bool SemanticEquals<T>(
T lhs, T rhs, Func<T, T, bool> f) {
return BaseEquals(lhs, rhs) && f(lhs, rhs);
}
最後還有一個SemanticSequenceEquals
方法接受兩個IEnumerable<T>
實例來比較,和的IEqualityComparer情況下,將獲得通過Enumerable.SequenceEquals
呼籲列表中的每個元素對。
public static bool SemanticSequenceEquals<T, U, V>(U lhs,
U rhs,
V comparator)
where U : IEnumerable<T>
where V : IEqualityComparer<T> {
return SemanticEquals(lhs, rhs, (l, r) => lhs.SequenceEqual(rhs, comparator));
}
} // end of ConstraintChecker
的SemanticSequenceEquals
的一點是,你不必定義兩個比較器,每當你想比較這兩個IEnumerable<T>
和T
實例;現在您只需指定一個IEqualityComparer<T>
,並且您在調用SemanticSequenceEquals
時也會處理列表。所以我可以擺脫BasketEqualityComparer類,這很好。
但是有一個問題。 C#編譯器不能找出所涉及的類型,當你調用SemanticSequenceEquals:
// Error! Compiler can't infer the type parameters.
return ConstraintChecker.SemanticSequenceEquals(lhs, rhs,
new FruitEqualityComparer());
如果我明確指定,它的工作原理:
return ConstraintChecker.SemanticSequenceEquals<Fruit, IEnumerable<Fruit>,
IEqualityComparer<Fruit>> (lhs, rhs, new FruitEqualityComparer());
很顯然,這是一個巨大的麻煩,這是不是很乾。我可以在這裏更改什麼,以便我不必明確寫入類型參數?
爲什麼我沒有想到這一點?這是最明顯的解決方案,但我仍然必須明確指定「T」的類型參數。當它是兩個方法參數的共享類型參數時,它看起來像編譯器無法推斷T. – 2010-05-18 01:48:28