我对流畅的界面有疑问。
我们有一些对象用作 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对象的构造和设置得当,但还是与预期的用法不兼容。