我可以在C#泛型约束中指定"超类型"关系吗?

the*_*oop 6 c# generics delegates constraints

我有一个带有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
    }
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,编译器对此进行了抨击('Collection.Equals()'没有定义类型参数'T').有没有办法指定这种类型的约束/操作?

Jon*_*eet 5

不,恐怕你不能指定这样的约束。(我有时也想要它。)

可以在非泛型类中编写具有两个类型参数的静态泛型方法:

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
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

如果您愿意,您甚至可以在泛型类上调用实例方法:

// Implementing the static method:
return first.Equals(second, new EqualityComparer<T>(comparer));
Run Code Online (Sandbox Code Playgroud)

集合的实例方法就是:

public bool Equals(Collection<T> other, EqualityComparer<T> eq)
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

这使用了可用于从 C# 2 开始创建委托的逆变。

  • 是的,这是完全有道理的——你可以指定一个类型参数必须是其他东西的*子类*,那么为什么不反过来呢?(Java 允许这样做,使用 `T super Foo` 而不是 `T extends Foo`,顺便说一句。) (2认同)