8

流暢なインターフェースについて質問があります。

SQLインターフェイスのパラメータオブジェクトとして使用されるオブジェクトがいくつかあります。例を次に示します。

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

これらのパラメーターのいくつかについて、いくつかの特殊なオプションを有効にしたいのですが、Int32メソッド(多くのパラメーターの1つにすぎません)にプロパティを追加する代わりに、流暢なインターフェイスを調べたいと思いました。

これが私が調べているものを追加した例です:

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

これらの2つのオプションは、このタイプのパラメーターには意味がないことを私は知っていますが、それは問題の内容ではありません。

上記の場合、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オブジェクトは適切に構築および設定されていますが、意図した使用法と互換性がなくなったためです。

4

2 に答える 2

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());

再:後で適用される状態を構築するか、各呼び出しで直接適用するか、どちらの場合でも実際の不可逆的な副作用がない場合、それは問題ではなく、あなたの個人的な好み次第です。オプションが各メソッド呼び出しでコミットされ、それを元に戻す可能性がある場合は、最初に状態を構築してから適用することをお勧めします。パラメータオブジェクトを適用するときにプロパティ間で検証を行う場合は、検証フィードバックを正しく取得できるように、直接適用する方がよい場合があります。

于 2008-10-20T10:51:37.617 に答える
1

ただし、メソッドをオーバーロードすることはできます。たとえば、Substitute()の場合。通常、メソッドの静的バージョンとインスタンスバージョンの両方を持つことはできませんが、拡張メソッドが役立つ場合があります...しかし、Substituteの2つのバージョンの意味が異なる場合は、単に異なるタイプが返される方がクリーンです。 Substitute()の2つのバリアントが競合することはありません。

于 2008-10-20T10:52:23.637 に答える