如果我有
public class AImplementation:IAInterface
{
void IAInterface.AInterfaceMethod()
{
}
void AnotherMethod()
{
((IAInterface)this).AInterfaceMethod();
}
}
如何在不显式转换的情况下从 AnotherMethod()
调用 AInterfaceMethod()
?
不使用转换运算符也有很多方法。
技巧 #1:使用“as”运算符代替转换运算符。
void AnotherMethod()
{
(this as IAInterface).AInterfaceMethod(); // no cast here
}
技巧 #2:通过使用本地变量进行隐式转换。
void AnotherMethod()
{
IAInterface ia = this;
ia.AInterfaceMethod(); // no cast here either
}
技巧 #3:编写扩展方法:
static class Extensions
{
public static void DoIt(this IAInterface ia)
{
ia.AInterfaceMethod(); // no cast here!
}
}
...
void AnotherMethod()
{
this.DoIt(); // no cast here either!
}
技巧 #4:引入一个辅助函数:
private IAInterface AsIA => this;
void AnotherMethod()
{
this.AsIA.IAInterfaceMethod(); // no casts here!
}
as
被认为是“显式强制类型转换”(我不知道这是否符合语言规范定义,或者这个问题在那种情况下是否毫无意义)。 - Pavel MinaevA
的作者打算允许派生类调用和/或覆盖基类实现,则类A
的作者应该创建一个受保护的虚拟方法,而不是一个显式的接口方法。如果类A
的作者没有这样的意图,而类B
的作者希望类A
的作者这样做,则类B
的作者应该(1)找到另一个类来扩展,例如编写自己的类,或(2)与类A
的作者协商。继承必须是类的一个内置特性。 - Eric Lippertprivate IAInterface IAInterface => this;
void IAInterface.AInterfaceMethod()
{
}
void AnotherMethod()
{
IAInterface.AInterfaceMethod();
}
我试过这个方法,它有效...
public class AImplementation : IAInterface
{
IAInterface IAInterface;
public AImplementation() {
IAInterface = (IAInterface)this;
}
void IAInterface.AInterfaceMethod()
{
}
void AnotherMethod()
{
IAInterface.AInterfaceMethod();
}
}
另一种方法(这是Eric技巧#2的一个衍生版本,如果接口未实现,也应该在编译时出错)
IAInterface AsIAInterface
{
get { return this; }
}
这是不可能的原因,没有显式或隐式转换,因为您可以在同一类中实现更多接口,而所有接口都可以提供相同的方法(相同的名称和签名)。 考虑以下示例:
class MyClass : IAInterface1, IAInterface2
{
void IAInterface1.DoSomething() { }
void IAInterface2.DoSomething() { }
void AnotherMethod
{
this.DoSomething(); // ⚡ERROR
// how should the compiler know which method to link?
}
}
但是,在我看来,针对您的使用情况,最简单且最优雅(且性能最佳)的解决方案是提供两种方法:
class MyClass : IAInterface
{
void IAInterface.DoSomething() => this.DoSomething();
private void DoSomething
{
}
void AnotherMethod
{
this.DoSomething();
}
}
你不能这样做,但如果你必须经常这样做,你可以定义一个方便的帮助程序:
private IAInterface that { get { return (IAInterface)this; } }
每当你想调用一个显式实现的接口方法时,你可以使用that.method()
代替((IAInterface)this).method()
。
还有一种方法(不是最好的):
(this ?? default(IAInterface)).AInterfaceMethod();
((IAInterface)this)
。但不利之处在于,如果 this
为 null
,而且本不应该为 null
,它将会在默认实例中调用 AInterfaceMethod
,而非抛出异常。几乎肯定不是期望的行为。 - ToolmakerSteve你不能只是从方法签名中删除 "IAInterface." 吗?
public class AImplementation : IAInterface
{
public void AInterfaceMethod()
{
}
void AnotherMethod()
{
this.AInterfaceMethod();
}
}
public
(并从声明中删除显式的IAInterface.
),这使其比您想要的更广泛可见。因此,我不建议这样做,只是提到这是一种可能的替代解决方案。 - ToolmakerSteve