如何实现一个非泛型的通用参数。

7

我有一个接口有两个通用参数,但其中一个参数预计由类实现提供。

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

然而,另一个接口有一个方法,它以IA的实例作为参数 - 但是,每个实例必须是相同的(同一类可以使用多个X,但它永远不会使用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> { ... }

当然,我不想写出参数V,因为我不能为其选择一个值。参数U已经决定了V的值!但是,我不能简单地删除V,因为那样我就无法编写约束条件。
另一种解决方案是不使用约束条件:
public interface IB<T> {
   void MyMethod(IA<T> value);
}

但是这种方法不能确保IB的实现只收到一个IA的实现(即它将能够同时接收XY,而且它不应该这样做)。
是否有任何方法可以避免在接口IB中创建泛型参数V(在第一种解决方案中),同时仍然互斥地实现IA?编译器无法推断出V的类型并允许我只编写class Z<T> : IB<T, X<T>>吗?或者这种情况没有出现在语言规范中/选择不实现的原因是什么?

接口IB应该与接口IA具有相同的泛型参数。我不明白为什么你需要将X<T>作为类型传递。你已经足够定义MyMethod(IA<T,U> value),它将限制为XY但不能同时存在。 - Reactgular
1个回答

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

有没有办法在不创建接口IB中的通用参数V(在第一种解决方案中)的情况下,仍然互斥IA的实现?编译器无法推断V的类型并允许我只编写class 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

在您的IB接口中仍然需要使用IA<T,U>。我认为没有简单的方法可以避免这个问题。


没错,谢谢。虽然我的问题中的类型是可以逻辑推断的,但这是因为存在类型的冗余。 - Mephy
@Mephy 如果我理解正确的话,你想要从 IB 中移除使用 IA。我不确定你是否可以(或者至少不容易)。 - Reactgular
1
@MathewFoscarini 不,我没有。只是因为我需要指定IAU参数和IBV参数相同,所以出现了重复。你的答案完全可以,我能够轻松地删除IBU参数。 - Mephy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接