2013-09-26 39 views
1

我一直在研究空接口和抽象类,从我读过的内容来看,它们通常是不好的做法。我打算将它们用作我撰写的小型搜索应用程序的基础。我会写最初的搜索提供者,其他人也可以创建他们自己的提供者。我的代码的意图是强制任何人想要实现它们的类之间的关系。空接口和抽象类实施结构

有人可以叮叮当当地描述是否以及为什么这仍然是一个不好的做法,以及如果有任何替代方法可用。

namespace Api.SearchProviders 
{ 
    public abstract class ListingSeachResult 
    { 
     public abstract string GetResultsAsJSON(); 
    } 

    public abstract class SearchParameters 
    { 
    } 

    public interface IListingSearchProvider 
    { 
     ListingSeachResult SearchListings(SearchParameters p); 
    } 
    } 
+0

这可能更适合于http://codereview.stackexchange.com/ –

+4

什么是空类会有用?它完全没用。删除它,让你的方法期待一个“对象”。 –

+1

你打算如何在'SearchListings'中使用'p'?你确定你不想在这个空白的界面/类中有东西吗?如果你真的这样做,我会用一个空的接口去做,而不是一个空的抽象类,这样你仍然可以选择继承别的东西。 –

回答

1

空的类和接口通常只是“可用的”作为通用约束;这些类型本身并不可用,通用约束通常是唯一可以将其与其他有用的结合使用的上下文。例如,如果IMagicThing封装了一些值,一些实现是可变的,有些是没有,这要记录与IMagicThing关联的值类似的方法可以写成:

void RecordValues<T>(T it) where T:IImagicThing,IIsImmutable {...} 

其中IIsImmutable是一个空接口的合同说任何实现它并为任何财产报告一些价值的类都必须永远更多地报告该财产的相同价值。按指示书写的方法可以知道其参数在合同中有义务表现为IMagicThing的不可变实现。

从概念上讲,如果接口的各种实现将对他们的行为做出不同的承诺,那么能够将这些承诺与约束结合起来似乎很有帮助。不幸的是,这种方法存在一个相当讨厌的限制:除非知道满足所有约束的特定类型以及从哪个对象派生出来,否则不可能将对象传递给上述方法。如果只有一个约束,则可以将该对象转换为该类型,但如果有两个或更多个,则该方法无效。

由于使用约束泛型当上述困难的,这是更好地表达“一个IMagicThing这将是不可改变的”通过定义从IMagicThing派生,但没有增加新成员的接口IImmutableMagicThing的概念。期望IImmutableMagicThing的方法不会接受任何不实现不可变接口的IMagicThing,即使它碰巧是不可变的,但如果有一个IMagicThing的引用实现了IImmutableMagicThing,那么可以将该引用强制转换为后一种类型并将其传递给需要它的例程。

顺便提一下,我可以看到一个空类类型的其他用法:作为身份标记。一个类不需要任何成员作为字典键,监视器锁或弱引用的目标。特别是如果有一个与这种用法相关的扩展方法,为此目的定义一个空类可能比使用Object方便得多。