【问题标题】:Visual Studio code generated when choosing to explicitly implement interface选择显式实现接口时生成的 Visual Studio 代码
【发布时间】:2010-06-03 09:22:07
【问题描述】:
抱歉标题含糊,但我不确定这叫什么。
假设我将IDisposable 添加到我的班级,Visual Studio 可以为我创建方法存根。但它会创建像这样的存根:
void IDisposable.Dispose()
我不遵循这种语法的作用。为什么要这样而不是public void Dispose()?
对于第一种语法,我不知道如何从我的类中(在我的析构函数中)调用 Dispose()。
【问题讨论】:
标签:
visual-studio
code-generation
methods
interface
【解决方案1】:
当您显式实现接口成员时,即生成的代码正在执行的操作,您无法通过类实例访问该成员。相反,您必须通过接口的实例调用它。例如:
class MyClass : IDisposable
{
void IDisposable.Dispose()
{
// Do Stuff
}
~MyClass()
{
IDisposable me = (IDisposable)this;
me.Dispose();
}
}
这使您可以使用同名成员实现两个接口,并独立显式调用任一成员。
interface IExplict1
{
string InterfaceName();
}
interface IExplict2
{
string InterfaceName();
}
class MyClass : IExplict1, IExplict2
{
string IExplict1.InterfaceName()
{
return "IExplicit1";
}
string IExplict2.InterfaceName()
{
return "IExplicit2";
}
}
public static void Main()
{
MyClass myInstance = new MyClass();
Console.WriteLine( ((IExplcit1)myInstance).InstanceName() ); // outputs "IExplicit1"
IExplicit2 myExplicit2Instance = (IExplicit2)myInstance;
Console.WriteLine( myExplicit2Instance.InstanceName() ); // outputs "IExplicit2"
}
【解决方案2】:
Visual Studio 为您提供两种选择:
您通常选择第一个(非显式):它会提供您想要的行为。
如果您从两个不同的接口继承相同的方法,即多重继承(通常不这样做),“显式”选项很有用。
【解决方案3】:
接口类型的成员始终是公共的。这也要求他们的方法实现也是公开的。例如,这不会编译:
interface IFoo { void Bar(); }
class Baz : IFoo {
private void Bar() { } // CS0737
}
显式接口实现提供了允许方法私有的语法:
class Baz : IFoo {
void IFoo.Bar() { } // No error
}
一个典型的用途是隐藏基本接口类型的实现。 IEnumerable 就是一个很好的例子:
class Baz : IEnumerable<Foo> {
public IEnumerator<Foo> GetEnumerator() {}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { }
}
注意通用版本是如何访问的,非通用版本是隐藏的。这既不鼓励使用它,又避免了由于重复方法而导致的编译错误。
在您的情况下,显式实施 Dispose() 是错误的。您编写 Dispose() 以允许客户端代码调用它,强制它强制转换为 IDisposable 以使调用没有意义。
此外,从终结器调用 Dispose() 是一种代码异味。标准模式是向您的类添加受保护的 Dispose(bool disposing) 方法。