我有一个关于流畅接口的问题。
我们有一些对象作为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
)
那么Substitute就必须是实例属性,而Precision则是静态方法。当然这段代码无法编译,因为我不能同时拥有同名的静态和非静态属性或方法。
我该怎么做?我完全错了吗?
在重新阅读问题时,我有一个想法,下面的不同语法是否更有意义?
SqlParameter.Int32(":ID", 1234).With
.Precision(15)
.Substitute
在这种情况下,两者都将是With返回的任何实例方法,它将是一个专门的类或接口,用于像这样的SqlParameter选项。我不确定是否想要删除.With部分,因为这将公开对象的所有方法,而不仅仅是流畅的方法。
建议和一些好的url链接将会非常受欢迎,我已经搜索了许多示例,但它们往往展示如下示例:
order
.AddFreeShipping()
.IncludeItem(15)
.SuppressTax();
(摘自此页面)
编辑:回应后的跟进 来自@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());
采用这种方法,With必须获取对象,并将其应用于参数。我对此没有问题。
如果我使用我添加的语法作为示例,那么它会像这样:
SqlParameter.Int32(":ID", 1234).With
.Precision(15)
.Substitute());
在这种情况下,With不会知道链结束的时间,因此每个选项都必须直接应用其效果。
哪个更好?是让选项构建一个效果对象,稍后必须应用该对象,还是让每个效果直接应用其效果? 我的决定: 正如@marxidad所说,如果更改是不可逆转的,并且可能会被撤销,那么我会采用建立状态并在某些时候失败的异常方式。
然而,在这种情况下,我选择了一种更简单的方法,直接修改SqlParameter对象。
在这种情况下,我的代码将如下所示:
SqlParameter.Int32(":ID", 1234).With
.Precision(15)
.Substitute());
编辑: 哎呀,当我只关注一件事情时就会这样。
我不能使用那个语法,我将使用以下语法,正如@marxidad所建议的:
SqlParameter.Int32(":ID", 1234).With(new SqlParameterOption()
.Precision(15)
.Substitute());
原因当然是使用以SqlParameter对象为参数的方法无法处理With返回的对象,因此虽然SqlParameter对象被构造并设置正确,但它与预期的用法不兼容。