我有一个带有Equals方法的集合类,我希望在方法中传递每个项目之间的相等性检查。此外,我想允许委托类型操作T的超类以及T本身:
public delegate bool EqualityComparer<T>(T x, T y);
public class Collection<T>
{
//...
public bool Equals<U>(Collection<T> other, EqualityComparer<U> eq) where T : U
{
// code using eq delegate to test equality between
// members of this and other collection
}
}
不幸的是,编译器对此进行了抨击('Collection.Equals()'没有定义类型参数'T')。有没有办法指定这种类型的约束/操作?
答案 0 :(得分:4)
不,我担心你不能指定这样的约束。 (我偶尔也想要它。)
你可以在非泛型类中编写一个带有两个类型参数的静态泛型方法,但是:
public delegate bool EqualityComparer<T>(T x, T y);
public class Collection
{
public static Equals<T, U>(Collection<T> first,
Collection<T> second,
EqualityComparer<U> comparer) where T : U
{
}
}
如果您愿意,甚至可以在泛型类上调用该实例方法:
// Implementing the static method:
return first.Equals(second, new EqualityComparer<T>(comparer));
集合的实例方法就是:
public bool Equals(Collection<T> other, EqualityComparer<T> eq)
{
// ...
}
这使用了从C#2开始创建代表的可用性。
答案 1 :(得分:1)
正如Jon所说,你不能以这种方式在约束中引用T,因为它是在类级声明的。
如果您可以编写方法而无法访问集合的私有状态(或者它们是内部的),那么您可以像这样重写:
public class Collection<T>
{
...
}
public static class CollectionExtentions
{
public static bool Equals<T,U>(
this Collection<T> first,
Collection<T> other,
EqualityComparer<U> eq) where T : U
{
... // legal to use eq here on the T values with collections
}
}
顺便提一下,我建议您使用Func<T,T,bool>
而不是您自己的命名代理
答案 2 :(得分:0)
如果您明确希望type参数是U的继承类,则不需要泛型,而是使用U作为参数的正式类型。 polimorfism开始了! :)