2008-10-20 101 views
8

我有一个流畅的接口问题。C#中的流畅接口

我们有作为参数对象的SQL接口的一些对象,这里有一个例子:

using (DatabaseCommand cmd = conn.CreateCommand(
    "SELECT A, B, C FROM tablename WHERE ID = :ID", 
    SqlParameter.Int32(":ID", 1234))) 
{ 
    ... 
} 

对于一些参数,我想使一些专门的选项,而是中加Int32方法的更多属性(这只是其中的一个),我认为我会研究流畅的接口。

此处,我已经添加了什么,我寻找到一个例子:

SqlParameter.Int32(":ID", 1234).With(SqlParameterOption 
    .Substitute 
    .Precision(15) 
) 

我知道这两个选项就没有意义了这种类型的参数,但是这并不是问题是什么。

在上面的例子中,Substitute必须是SqlParameterOption类的静态属性(或方法,如果我只是添加一些括号),而Precision将不得不是一个实例方法。

如果我重新排列它们,该怎么办?

SqlParameter.Int32(":ID", 1234).With(SqlParameterOption 
    .Precision(15) 
    .Substitute 
) 

然后替代将必须是实例属性和精度静态方法。这当然不会编译,我不能同时使用静态和非静态属性或方法。

我该怎么做?我完全在错误的轨道上吗?

重读这个问题时,我有一个想法,下面的这个不同的语法会更有意义吗?

SqlParameter.Int32(":ID", 1234).With 
    .Precision(15) 
    .Substitute 

在这种情况下,任何方式都将是实例方法随着返回,这将是一个专门的类或SqlParameter选项这样的接口。我不确定我想倾倒。与部分,因为这会暴露对象的所有方法,而不仅仅是流利的

建议和一些好的网址的将是最受欢迎的,我已经冲刷了很多例子,但他们往往会表现出这样的例子:

order 
    .AddFreeShipping() 
    .IncludeItem(15) 
     .SuppressTax(); 

(从this page解除)


编辑:回复后的跟进 来自@marxidad

class SqlParameterOption 
{ 
    public SqlParameterOption Precision(int p) {/* ... */; return this;} 
    public SqlParameterOption Substitute() {/* ... */; return this;} 
    /* ... */  
} 

/* ... */ 
SqlParameter.Int32(":ID", 1234).With(new SqlParameterOption() 
              .Precision(15) 
              .Substitute()); 

用这种方法,将不得不采取该对象,并将其应用于参数。我很好。

如果我用我说作为一个例子语法,这将是这样的:

SqlParameter.Int32(":ID", 1234).With 
           .Precision(15) 
           .Substitute()); 

在这种情况下,不知道什么时候结束的链条,所以每个选项就必须运用其直接影响。

什么是首选?这些选项是否会构建一个效果对象,以后再应用,或者每个效果都直接应用其效果?

决定: 作为@marxidad说,如果改变是不可逆的,可能是受到了逆转,建立国家和在某些时候有一个例外,就是失败,我会走的路。

但是,在这种情况下,我将使用一种更简单的方法直接修改SqlParameter对象。

在这种情况下,我的代码如下所示:

SqlParameter.Int32(":ID", 1234).With 
           .Precision(15) 
           .Substitute()); 

编辑:尔加,这是怎么一回事呢,当我专注于一两件事。

我不能使用的语法,我会用下面去,作为建议的@marxidad

SqlParameter.Int32(":ID", 1234).With(new SqlParameterOption() 
              .Precision(15) 
              .Substitute()); 

的原因当然是该采取的SqlParameter对象作为参数的方法是不能的来处理由With返回的对象,因此虽然SqlParameter对象的构造和设置正确,但它与预期用法不兼容。

回答

8

SqlParameterOption's方法都可以实例方法返回相同的对象:

class SqlParameterOption 
{ 
    public SqlParameterOption Precision(int p) {/* ... */; return this;} 
    public SqlParameterOption Substitute() {/* ... */; return this;} 
    /* ... */  
} 

/* ... */ 
SqlParameter.Int32(":ID", 1234).With(new SqlParameterOption() 
              .Precision(15) 
              .Substitute()); 

回复:建立国家要对直接与每个呼叫应用后应用,如果没有真正的irreverisible副作用在任何一种情况下都会产生影响,那么这并不重要,并且取决于您的个人喜好。如果选项是针对每个方法调用进行的,并且有可能需要撤销该选项,那么您可能需要先建立状态并应用它。如果参数对象在您应用它们时为您进行属性验证,那么使用直接应用程序可能会更好,因此您将获得正确的验证反馈。

1

虽然您可以重载方法。例如,如果它是Substitute()。你通常不能同时拥有方法的静态和实例版本,但是扩展方法可能有些用处......但是如果两个版本的替代品具有不同的含义,那么简单地返回不同的类型会更清晰,所以Substitute()的两个变体不能冲突。

+0

在这种情况下,关于意义不会有任何冲突,问题更多的是关于如何组织代码来获得我想要的,语法上的。新增选项对象的实例解决了这个问题,如marxidad所示。 – 2008-10-20 11:36:41