我有一些看起来像下面的代码。首先,我有一些域类和一些特殊的比较器。如何让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