是否可以使用可选的实现方法定义接口?例如,我的核心库中有以下接口定义作为IDataReader:
public interface IDataReader<T> {
void StartRead(T data);
void Stop();
}
Run Code Online (Sandbox Code Playgroud)
但是,在我当前的实现中,从未使用或实现过Stop()方法.在我的所有实现类中,必须使用throw NotImplementedExcetion()作为默认值来实现此方法:
class MyDataReader : IDataReader<MyData> {
...
public void Stop()
{
// this none implementaion looks like uncompleted codes
throw NotImplementedException();
}
Run Code Online (Sandbox Code Playgroud)
当然,我可以删除throw异常代码并将其保留为空.
当我设计这个数据阅读器界面时,我认为它应该提供一种方法来停止阅读过程.也许我们将来某个时候会使用Stop().
无论如何,不确定是否可以将此Stop()方法作为可选的实现方法?我能想到的唯一方法是要么定义两个接口,一个是stop,另一个是没有IDataReader和IDataReader2.另一个选择是将这个打破到这样的接口:
interface IDataReader<T> {
void StartRead(T data);
}
interface IStop {
void Stop();
}
Run Code Online (Sandbox Code Playgroud)
在我的实现案例中,我必须转换或使用IStop来检查我的实现是否支持Stop()方法:
reader.StartRead(myData);
....
// some where when I need to stop reader
IStop stoppable = reader as IStop;
if (stoppable != null ) stoppable.Stop();
...
Run Code Online (Sandbox Code Playgroud)
我还是要写那些代码.有什么建议?不确定是否有任何方法可以在.Net或C#中的接口中定义可选的实现方法?
有趣.我必须在这里引用你的话:
但是,在我当前的实现中,从未使用或实现过Stop()方法.在我的所有实现类中,必须使用throw NotImplementedExcetion()作为默认值来实现此方法:
如果是这种情况,那么您有两种选择:
更新我认为方法可选的唯一方法是将方法分配给变量(类似于方法签名的委托类型),然后在尝试在任何地方调用它之前评估方法是否为null.
这通常是针对事件处理程序完成的,其中处理程序可以存在或不存在,并且可以被认为是可选的.
有关信息,BCL中相当常见的另一种方法是Supports*在同一个界面上,即
bool SupportsStop {get;}
void Stop();
Run Code Online (Sandbox Code Playgroud)
(例如,这样的例子IBindingList).
我不是假装它是"纯粹的"或任何东西,但它有效 - 但它意味着你现在有两种方法来实现每个功能,而不是一个.单独的接口(IStoppableReader例如)可能是优选的.
有关信息,如果实现在所有实现之间是通用的,那么您可以使用扩展方法; 一个简单的例子:
public static void AddRange<T>(this IList<T> list, IEnumerable<T> items) {
foreach(T item in items) list.Add(item);
}
Run Code Online (Sandbox Code Playgroud)
(或您的界面的等效物).如果您针对具体类型提供更专业的版本,那么它将优先(但仅当调用者知道变量作为具体类型而不是接口时).因此,如上所述,任何人都故意使用List<T>静态使用List<T>的版本AddRange; 但如果有一个List<T>但只知道它IList<T>,它将使用扩展方法.
如果该方法不适合您的实现,InvalidOperationException就像大多数迭代器在调用Reset它们时那样抛出.一种替代方案NotSupportedException往往被使用System.IO.后者更符合逻辑(因为它与对象的当前状态无关,只是它的具体类型),但前者在我的经验中更常用.
但是,最好只在实际需要时将东西放入界面中 - 如果你仍处于可以删除的位置,Stop如果我是你,我会这样做.
对语言或CLR中的可选接口成员没有统一支持.