Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当多个泛型类型参数相同时,如何解决接口方法签名不明确的问题_C# - Fatal编程技术网

C# 当多个泛型类型参数相同时,如何解决接口方法签名不明确的问题

C# 当多个泛型类型参数相同时,如何解决接口方法签名不明确的问题,c#,C#,在下面的示例中,实现类的方法是否可以显式地告诉编译器它实现了哪个接口成员? 我知道可以解决接口之间的模糊性,但这里它在一个接口内 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) { } // amb

在下面的示例中,实现类的方法是否可以显式地告诉编译器它实现了哪个接口成员? 我知道可以解决接口之间的模糊性,但这里它在一个接口内

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
}
接口IFoo
{
空心钢筋(A);
空心钢筋(B);
}
Foo类:IFoo
{
公共空栏(字符串a){}
公共无效条(字符串b){}//不明确签名
}

您只需删除重复的行:

interface IFoo<A, B>
{
    void Bar(A a);
    void Bar(B b);
}

class Foo : IFoo<string, string>
{
    public void Bar(string a) { }
}
接口IFoo
{
空心钢筋(A);
空心钢筋(B);
}
Foo类:IFoo
{
公共空栏(字符串a){}
}
在这种情况下,使用
void Bar(string a)
的单个实现可以实现接口的两种方法

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);
}
公共接口IBar
{
空隙率(T);
}
公共接口IFoo:IBar
{
空心钢筋(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);
    }
}
公共类Foo:IFoo
{
void IFoo.Bar(字符串b)
{
Console.WriteLine(“IFoo.Bar:+b”);
}
无效IBar.Bar(字符串t)
{
控制台写入线(“IBar.Bar:+t”);
}
}
但如果要使用它,必须将实例强制转换为特殊接口:

var foo = new Foo();
((IFoo<string, string>)foo).Bar("Hello");
((IBar<string>foo).Bar("World");
var foo=new foo();
((IFoo)foo.Bar(“你好”);
((IBarfoo.Bar)(“世界”);
这将按预期打印:

IFoo<string, string>.Bar: Hello
IBar<string>.Bar: World
IFoo.Bar:您好
酒吧:世界
希望这能对你有所帮助。我不认为有其他方法可以做到这一点

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

您不能这样做

<代码>()<代码>在这种情况下将是模棱两可的。考虑将接口方法更改为<代码> BAAL()/<代码>,代码> BARB()/<代码> < /P>


也可以考虑使用<代码> < <代码> >代码> b>代码>更有意义的名称(例如,<代码> IFoo < /代码>),然后您的方法可以是<代码> BAKEY()/<代码>和<代码> BalValue>>(<)/>代码> < /P>您是误解接口。您只需要代码>公共空格条(字符串A){}。您正在实现接口的契约,而不是方法定义本身。当

A
=
B
向外部调用方调用时,这两个
定义之间没有区别。它们是同一个。我认为您无法解决这一问题,因为如果您不使用泛型,那么就编写它而不使用g泛型,看看会发生什么,也许这有助于你理解为什么不可能进一步解释,你的界面上说“任何实现我的人都应该实现
Bar(A)
Bar(B)
”。当传递
时,合同变成“任何实现我的人都应该实现
Bar(string)
”@Rob我不认为我误解了接口。我犯了一个设计错误,没有考虑到一个实现类可以为a和B传递相同的类型,因此产生了签名冲突。我在这里问这个问题是因为C#有一些语法方法来表示它们代表的接口参数,like:
公共空栏(字符串a),其中a表示IFoo::a{}
但现在我确定没有,我将使接口的方法名称唯一。谢谢。更改接口的成本很高,我试图避免,但似乎没有办法。我将方法名称更改为BarA和BarB。谢谢。这使代码可以编译,但无法解决问题。
Bar(A)
Bar(B)
在语义上是不同的,因此不能用相同的方法实现。如果无法解决歧义,我将不得不更改方法名称。@ArmyNoodles-是的,这是您必须做的。