强制声明(.NET)使用接口而不是具体实现

强制声明(.NET)使用接口而不是具体实现

问题描述:

在C++中,你可以做到以下几点:强制声明(.NET)使用接口而不是具体实现

class base_class 
{ 
public: 
    virtual void do_something() = 0; 
}; 

class derived_class : public base_class 
{ 
private: 
    virtual void do_something() 
    { 
     std::cout << "do_something() called"; 
    } 
}; 

derived_class覆盖方法do_something()并使其private。效果是,调用此方法的唯一方法是这样的:

base_class *object = new derived_class(); 
object->do_something(); 

如果声明的对象作为derived_class类型的,你不能调用该方法,因为它是私有的:

derived_class *object = new derived_class(); 
object->do_something(); 
// --> error C2248: '::derived_class::do_something' : cannot access private member declared in class '::derived_class' 

我认为这很好,因为如果你创建一个用作接口的抽象类,你可以确保没有人意外地声明一个字段为具体类型,但总是使用接口类。

由于在C#/ .NET中一般情况下,您不允许在覆盖某个方法时将访问范围从public缩小为private,有没有办法在此实现类似效果?

如果你明确地实现了一个接口,这至少会鼓励人们在声明中使用接口类型。

interface IMyInterface 
{ 
    void MyMethod(); 
} 

class MyImplementation : IMyInterface 
{ 
    void IMyInterface.MyMethod() 
    { 
    } 
} 

一个只会看到的MyMethod铸造实例IMyInterface后。如果声明使用接口类型,则在随后的使用中不需要转换。

MSDN page on explicit interface implementation(感谢卢克,节省了我几秒钟^^)

IMyInterface instance = new MyImplementation(); 
instance.MyMethod(); 

MyImplementation instance2 = new MyImplementation(); 
instance2.MyMethod(); // Won't compile with an explicit implementation 
((IMyInterface)instance2).MyMethod(); 
+0

这个效果是我想要的,谢谢。 – gammelgul 2010-05-05 11:33:49

+0

+1我刚刚学到了一些新东西! – BritishDeveloper 2010-05-05 11:44:32

+0

+1谢谢你,也学到了新的东西! – Deano 2011-03-04 10:11:38

可以通过标记为new来降低方法的可用性。

MSDN's CA2222: Do not decrease inherited member visibility的例子:

using System; 
namespace UsageLibrary 
{ 
    public class ABaseType 
    { 
     public void BasePublicMethod(int argument1) {} 
    } 
    public class ADerivedType:ABaseType 
    { 
     // Violates rule: DoNotDecreaseInheritedMemberVisibility. 
     // The compiler returns an error if this is overridden instead of new. 
     private new void BasePublicMethod(int argument1){}  
    } 
} 

这是作为一个学术活动真的很有趣;如果你的代码真的依赖于不能在ADerivedType上调用BasePublicMethod,那是一个可疑设计的警告信号。

您可以在.NET世界也做到这一点,利用explicit interface implementation

举个例子,BindingList<T>实现IBindingList,但你必须将它转换为IBindingList看方法。

+1

它被称为显式接口实现:http://msdn.microsoft.com/en-us/library/aa288461.aspx – LukeH 2010-05-05 11:24:07

+0

@Luke感谢您的链接,我一直在努力寻找它:) – 2010-05-05 11:48:01

该策略应该实施的问题是该方法并非真正的私有方法。如果您想提及base_class,那么该方法现在是公开的。由于它是一种虚拟方法,用户代码将会执行derived_class::do_something()事件,尽管它被标记为私有。

+2

在这种情况下,这不是一个错误,而是一个功能。 – sbi 2010-05-05 11:21:20