C#:为什么我们必须将 class 显式转换为接口才能访问 class 的明确实现方法?

C#: Why must we explicitly cast a class to an interface to access the class's non-ambiguous implemented methods?

这是我拥有的 类 和接口:

public interface Baz {
    void someMethod();
}
public interface Foo {
    void someMethod();
}
public class Bar : Foo {
    void Foo.someMethod(){}
}

问题 1) 是否可以在运行时从 Bar 对象中删除 Foo 接口,或者向 Bar 对象添加 Baz 接口?

如果是,我可以提供有关如何完成的简短代码示例吗?

如果否,请继续回答问题 2 和 3。


问题 2) 为什么 C# 在将对象转换为它未实现的接口时不给出编译错误?如果您对问题 1 的回答是否定的,那么 mybar 永远不会是 Baz,那么为什么没有编译错误?

void myFunction(){
    Bar mybar = new Bar();
    (mybar as Baz).someMethod();
}

问题 3) 为什么 C# 不允许我在不转换为 Foo 的情况下从 Bar 对象调用 someMethod,即使它知道 someMethod 没有歧义?

void myFunction(){
    Bar mybar = new Bar();
    mybar.someMethod();//doesn't work
    mybar.Foo.someMethod();//doesn't work (C# could do this and give a compile error if Bar has a property or public variable with the same name as an interface that it implements to allow for this syntax)
    (mybar as Foo).someMethod();//works even though someMethod is not ambiguous.
    //The problem with this is that the keyword "as" has an option to return null, which I want to be very assured will never be the case.
}

无法在运行时向任何对象添加或删除接口实现。

as 运算符在 运行时检查对象的类型 和 returns 作为该类型的引用。在这种情况下,将返回 null 并抛出 NullReferenceException

mybar.Foo.someMethod()mybar 上访问名为 Foo 的成员,但没有这样的成员。声明 void Foo.someMethod(){} 仅表示该方法是为 Foo 接口显式定义的。

1) 不,不是

2) 因为你可以这样做:

public class Bar2 : Bar, Baz {
    ....
}

void myFunction(){
    Bar mybar = someConditionUnknownAtCompileTime? new Bar2(): new Bar();
    (mybar as Baz).someMethod();
}

3)

void myFunction(){
    Bar mybar = new Bar();

    // this method is unavailable without casting to 'Foo' - you can have 
    // many interfaces implemented and everyone can have 'someMethod' defined
    mybar.someMethod();

    // there is no field/property 'Foo' defined in `Bar`
    mybar.Foo.someMethod();

    // everything is OK
    (mybar as Foo).someMethod(); 
}

广告。 1)不,这是不可能的。我认为这需要动态规划。

广告。 2) as 运算符用于在运行时转换引用类型,但它不会给你一个异常,而是一个空值。如果你写了,它会引发异常,但因为你想在 null 上调用一个方法。 可以省略:(mybar as Foo)?.someMethod()

Ad 3) 这只是语法问题,不是歧义问题:)