Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.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
.NETC#祖父母的显式实现';父接口中的s接口方法_C#_.net_Inheritance_Interface_Explicit Implementation - Fatal编程技术网

.NETC#祖父母的显式实现';父接口中的s接口方法

.NETC#祖父母的显式实现';父接口中的s接口方法,c#,.net,inheritance,interface,explicit-implementation,C#,.net,Inheritance,Interface,Explicit Implementation,那个标题很有意思,不是吗 以下是我想做的: public interface IBar { void Bar(); } public interface IFoo: IBar { void Foo(); } public class FooImpl: IFoo { void IFoo.Foo() { /* works as expected */ } //void IFoo.Bar() { /* i'd like to do this, but it doe

那个标题很有意思,不是吗

以下是我想做的:

public interface IBar {
     void Bar();
}
public interface IFoo: IBar {
    void Foo();
}
public class FooImpl: IFoo {
    void IFoo.Foo()   { /* works as expected */ }
    //void IFoo.Bar() { /* i'd like to do this, but it doesn't compile */ }

    //so I'm forced to use this instead:
    void IBar.Bar()   { /* this would compile */ }
}
我的问题是这是。。。调用Bar()不方便:

所以。。。除了基本上将两个接口合并为一个接口之外,还有什么方法可以在我的类中声明
IFoo.Bar(){…}


如果没有,原因是什么?

您没有两个
IFoo
的实现;您只有一个。
CLR不区分来自接口树中不同点的接口副本

特别是,无法调用
IFoo.Bar()
;您只能调用
IBar.Bar


如果将一个单独的
Bar()
方法添加到
IFoo
,代码将正常工作。

由于IFoo扩展了Ibar,
void IFoo.Bar()
void Ibar.Bar()
是完全相同的函数。您不能两次定义同一个方法,这就是它不起作用的原因。

您希望该行为是什么?无论何时调用
IFoo.Bar()
它都将使用IBar中的定义,因为它只是一个接口,没有任何单独的
Bar()
概念。当使用强制转换到超类时,只能调用不同的方法,这是在重写类中的方法时,而不是实现和接口

当接口相互继承时,子接口几乎没有方法的所有权概念。就好像子接口中声明了两个方法一样


注意:潜在的过度并发症和大脑崩溃!!!小心阅读

我相信这是允许的,如果我错了,请纠正我:

public class IBar {
     virtual void Bar() {
         //IBar implementation of Bar
     }
}
public class IFoo: IBar {
    new virtual void Foo() {
        //implementation of Foo when currently casted to IFoo
    }
}
public class FooImpl: IFoo {
    new void Foo()   { /* implementation of Foo when cast to FooImpl */ }
    new void Bar()   { /* implementation of Bar when cast to FooImpl */ }
}
为清楚起见,在类名之前保留了I,但不再有任何接口。调用的方法将取决于对象被强制转换到的类

IBar b = new IBar();
b.Bar(); //calls IBar.Bar

IFoo f = new IFoo();
f.Bar(); //calls IFoo.Bar
f.Foo(); //calls IFoo.Foo
IBar fooAsBar = (IBar) f;
fooAsBar.Bar(); //calls IBar.Bar

FooImpl fi = new FooImpl();
fi.Bar(); //calls FooImpl.Bar
fi.Foo(); //calls FooImpl.Foo 
IFoo fooImplAsFoo = (IFoo) fi;
fooImplAsFoo.Bar(); //calls IFoo.Bar
fooImplAsFoo.Foo(); //calls IFoo.Foo
IBar fooImplAsBar = (IBar) fi;
fooImplAsBar.Bar(); //calls IBar.Bar

哦,您没有使用嵌套接口,它们只是从彼此继承。嵌套接口如下所示:

interface IBar {
    void Bar();

    interface IFoo {
        void Foo();
    }
}
public class FooImpl : IFoo {
    public void Foo() { /* implements IFoo.Foo */ }
    public void Bar() { /* implements IBar.Bar */ }
}

正如你所看到的,这是完全不同的。两个接口之间的关系只是一个接口只能在另一个接口内部使用。这是一个复杂而又有点棘手的话题。你可以D

在接口中使用new关键字可以显式隐藏在其扩展的接口中声明的成员:

public interface IBar
{
    void Bar();
}

public interface IFoo:IBar
{
    void Foo();
    new void Bar();
}

public class Class1 : IFoo
{
    void Bar(){}

    void IFoo.Foo(){}

    void IFoo.Bar(){}

    void IBar.Bar(){}
}

这只是显式实现接口方法的编译器约定。你可以这样写:

interface IBar {
    void Bar();

    interface IFoo {
        void Foo();
    }
}
public class FooImpl : IFoo {
    public void Foo() { /* implements IFoo.Foo */ }
    public void Bar() { /* implements IBar.Bar */ }
}

但是如果您想使用显式实现,那么编译器坚持使用声明该方法的接口的标识符名称。这是有道理的,IFoo还可以有一个Bar()方法。

我以前也曾对此感到失望,但我认为关键在于,根据定义,它是一个“显式”实现。除非您将对象强制转换为IBar,否则Bar方法的任何调用都隐式地依赖于对象最终实现IBar这一事实

把下面的例子看作是你想要什么的逻辑结论。理论上,FooImpl可以通过实现IFoo显式地实现Bar,理论上,派生类(FooChild)可以通过继承FooImpl来实现IBar。问题在于,这可能(至少)有两种不同的模糊“明确”实现路径:

public interface IBar {      void Bar(); } 
public interface IFoo: IBar {     void Foo(); }
public class FooImpl: IFoo {  
   void IFoo.Foo()   {  }     
   void IFoo.Bar()   { /* hypothetically, let's suppose this works */ }
   void IBar.Bar()   { /* this could then co-exist with the above.. */  } 
} 
public class FooChild : FooImpl
{
}

public class Owner
{
    public void Stuff()
    {
        FooChild child = new FooChild();
        // This invokes the "explicit" bar method (except not really...)
        ((FooImpl)child).Bar();     // Which version of Bar should be called here?
    }
}

我认为您需要让IFoo从IBar@StephanH接口不能实现任何东西;他们只能继承遗产。你是说别的吗?一个聪明的程序员在暴风雨中学会了他必须关心的事情和无关紧要的事情。。。我做对了吗?我不是建议为Bar()添加两个实现。像类FooImpl:IFoo{void IFoo.Bar(){}}这样简单的东西是不会编译的。我的意思是:由于IFoo不做任何事情来隐藏或覆盖Bar(),而且IFoo继承自IBar,所以我希望编译器将Bar()视为在IFoo中定义的(如果实现是隐式的,则会这样做,但对于显式的情况则不会). 在我看来,这似乎是一种前后矛盾的行为。或者我没有抓住显式接口实现背后的原因。也许你没有,我不知道。但请注意我回答的第一行,这只是一个惯例。如果IFoo和IBar都有一个Bar方法并且需要不同的实现,那么这个方法是有意义的。好的,我认为“嵌套接口”和“接口层次结构”一样。你说得对,嵌套是一个不同的概念。