C#:为什么我们必须将类显式强制转换为接口才能访问该类的非歧义实现方法
本文关键字:访问 接口 方法 实现 歧义 我们 为什么 转换 | 更新日期: 2023-09-27 18:33:31
以下是我拥有的类和接口:
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.
}
在运行时无法向任何对象添加或删除接口实现。
as
运算符在运行时检查对象的类型,并以该类型返回对它的引用。在这种情况下,将返回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();
}
Ad. 1)不,这是不可能的。我认为这需要动态编程。
广告2) as
运算符用于在运行时强制转换引用类型,但它不会给你一个异常,而是一个 null。如果你写了,它会引发一个异常,但因为你想在 null 上调用一个方法。这可以省略:(mybar as Foo)?.someMethod()
广告3)这只是语法问题,而不是歧义:)