如何解决歧义的接口方法签名,当多个泛型类型参数相同时发生

本文关键字:泛型类型参数 解决 何解决 歧义 方法 接口 | 更新日期: 2023-09-27 18:14:37

在下面的例子中,是否有一种方法可以让实现类的方法显式地告诉编译器它实现了哪个接口成员?我知道解决接口之间的歧义是可能的,但这里它是在一个接口内。

interface IFoo<A,B>
{
    void Bar(A a);
    void Bar(B b);
}
class Foo : IFoo<string, string>
{
    public void Bar(string a) { }
    public void Bar(string b) { }  // ambiguous signature
}

如何解决歧义的接口方法签名,当多个泛型类型参数相同时发生

我不认为您可以通过使用一个接口直接解决这个问题,因为在某些情况下方法签名可能是统一的。

如果你真的需要这个功能,我认为你必须引入一个新的接口,它将由foo派生。

public interface IBar<T>
{
    void Bar(T t);
}
public interface IFoo<A, B> : IBar<A>
{
    void Bar(B b);
}

现在你可以显式地实现这两个接口了:

public class Foo : IFoo<string, string>
{
    void IFoo<string, string>.Bar(string b)
    {
        Console.WriteLine("IFoo<string, string>.Bar: " + b);
    }
    void IBar<string>.Bar(string t)
    {
        Console.WriteLine("IBar<string>.Bar: " + t);
    }
}

但是如果你想使用它,你必须将你的实例强制转换为特殊的接口:

var foo = new Foo();
((IFoo<string, string>)foo).Bar("Hello");
((IBar<string>foo).Bar("World");

按预期打印:

IFoo<string, string>.Bar: Hello
IBar<string>.Bar: World

希望这对你有帮助。我认为没有别的方法可以做到这一点。

可以只显式地实现一个接口,这样只有在需要调用另一个方法时才需要强制转换。

你只需要删除重复的行:

interface IFoo<A, B>
{
    void Bar(A a);
    void Bar(B b);
}
class Foo : IFoo<string, string>
{
    public void Bar(string a) { }
}

在这种情况下,void Bar(string a)的单个实现实现了接口的两个方法。

实际上调用接口要困难得多。

你不能那样做。

Bar()在这种情况下是不明确的。考虑将接口方法改为BarA(), BarB()

另外,考虑使AB的名称更有意义(例如,IFoo<TKey, TValue>),那么你的方法可以是BarKey()BarValue()