如何实现非泛型的泛型参数

Mep*_*phy 7 c# generics

我有一个带有两个通用参数的接口,但其中一个参数应该由类实现提供.

public interface IA<T, U> { ... }
public class X<T> : IA<T, int> { ... }
public class Y<T> : IA<T, MyClass> { ... }
Run Code Online (Sandbox Code Playgroud)

但是,另一个接口有一个方法,它接受一个实例IA作为参数 - 但是,每个实例必须是相同的(同一个类可以采用多个X,但是它永远不会采用a Y,反之亦然).我试图把它作为一个通用的约束,但后来我有类似的东西

public interface IB<T, U, V> where U : IA<T, V> {
   void MyMethod(U value);
}
public class Z<T> : IB<T, X<T>, int> { ... }
Run Code Online (Sandbox Code Playgroud)

当然,我不想写那个参数V,因为我不能为它选择一个值.该参数U已经决定了V的值应该是什么!但是,我不能简单地删除V,因为那时我无法编写约束.


另一种解决方案是不使用约束:

public interface IB<T> {
   void MyMethod(IA<T> value);
}
Run Code Online (Sandbox Code Playgroud)

不过这样一来,我不能保证实施的IB将获得一个唯一的执行IA(即它能够同时接收XY,它不应该).


有没有办法避免V在接口中创建泛型参数IB(在第一个解决方案中),同时仍然相互排除实现IA?是否有任何特定的原因编译器无法推断出类型V并且只允许我编写class Z<T> : IB<T, X<T>>或者这种情况只是在语言规范中没有预期/被选择不实现?

Rea*_*lar 3

您已经有足够的泛型类型来限制IB<T,U>.MyMethod()接收XY。您只需将方法参数定义为接受特定类型。

    public interface IA<T,U> {}
    public class X<T> : IA<T,int> {}
    public class Y<T> : IA<T,string> {}

    public interface IB<T,U>
    {
        void MyMethod(IA<T,U> value);
    }

    IB<int,int> foo;
    X<int> a;
    Y<int> b;

    foo.MyMethod(a); // will compile
    foo.MyMethod(b); // will not compile
Run Code Online (Sandbox Code Playgroud)

有没有什么方法可以避免在接口 IB 中创建通用参数 V(在第一个解决方案中),同时仍然相互排除 IA 的实现?是否有任何特定原因导致编译器无法推断 V 的类型并允许我只编写类 Z : IB> 或者这种情况在语言规范中没有预期/被选择不实现?

我不认为 C# 中的推理是这样进行的。要推断 的类型,U可以MyMethod这样写。

    public interface IB<T>
    {
        void MyMethod<U>(IA<T,U> value);
    }

    IB<int> foo = null;
    X<int> a;
    foo.MyMethod(a); // int type is inferred by compiler
Run Code Online (Sandbox Code Playgroud)

你仍然需要IA<T,U>在你的IB界面中使用。我认为没有简单的方法可以解决这个问题。