C#:为什么我们必须显式地将类转换为接口来访问类的非模糊实现方法?

时间:2016-02-06 07:43:25

标签: c# interface casting ambiguity

以下是我的类和接口:

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

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

如果是,我可以获得一个简短的代码示例吗?

如果不是,请继续问题2和3。

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

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

问题3)为什么C#不允许我从Bar对象调用someMethod而不转换为Foo,即使它知道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.
}

3 个答案:

答案 0 :(得分:1)

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

as运算符在运行时检查对象的类型,并返回对该类型的引用。在这种情况下,系统会返回null并抛出NullReferenceException

mybar.Foo.someMethod()访问Foo上名为mybar的成员,但没有此类成员。声明void Foo.someMethod(){}只表示该方法是为Foo接口明确定义的。

答案 1 :(得分:0)

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(); 
}

答案 2 :(得分:0)

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

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

广告3)这只是语法问题,而不是含糊不清:)