1

Else一度だけ呼び出すことができるメソッドを含む流暢なインターフェイスを定義するクラスがあります。したがって、私が抱えている問題は、それが呼び出されたかどうかを確認する方法です。現在、私は追加のブールフィールドを介してこれを行っています:

public class FluentMatcher<T1, T2, TResult>
{
    private bool _elseValueSet;
    private TResult _elseValue;

    ...

    public FluentMatcher<T1, T2, TResult> Else(TResult resultIfElseRequired)
    {
        if (_elseValueCalled)
        {
            throw new ElseAlreadyAddedException();
        }
        _elseValue = resultIfElseRequired;
        _elseValueSet = true;
        return this;
    }
}

私はこれに不快感を覚えているので、次のようなことを考えています:

public class FluentMatcher<T1, T2, TResult>
{
    private Initialisable<TResult> _elseValue;

    ...

    public FluentMatcher<T1, T2, TResult> Else(TResult resultIfElseRequired)
    {
        if (_elseValue != null)
        {
            throw new ElseAlreadyAddedException();
        }
        _elseValue = new Initialisable<TResult>(resultIfElseRequired);
        return this;
    }
}

これにより、次の 2 つの疑問が生じます。

  1. フィールドが初期化されているかどうかをテストする方法は既にありますか? 構造体である可能性があるため、nullにすることはできないため、そうではないと想定しています。私は何かを逃しましたか?
  2. 私は新しいバージョンで何も修正しておらず、セマンティクスで遊んでいるような気がします。最初のバージョンは問題なく動作しますが、見苦しいと思います。この場合、ブールを使用しない正当な理由はありますか?
4

1 に答える 1

2

Elseメソッドは、非常によく似た別のインターフェイス (メソッドを持たないインターフェイス) を返す必要があるためElse、2 回呼び出すことはできません。

これは、私が取り組んでいたアプリの例です。

public class AddColumn
{
    internal AddColumn()
    {

    } 

    public NamedAddColumn Named(string name)
    {
        return new NamedAddColumn(name);
    }
}

public class NamedAddColumn
{
    protected string Name {get; set;}

    internal NamedAddColumn(string name)
    {
        Name = name;
    }

    public VarcharTypedAddColumn Varchar
    {
        get
        {
            return new VarcharTypedAddColumn(Name);
        }
    }
}

これは、データベースの移行を作成するための流暢なインターフェイスです。ご覧のとおり、Namedメソッドは非常に似たセマンティックな意味を持つ別のクラスを返します (どちらも列を表します) - ただし、このクラスでは、列に 2 回「名前を付ける」ことはできません。

これは、このインターフェイスを使用する方法です。

        db.AlterTable(tb => tb
                                .Named("Users")
                                .AddColumn(column => column
                                                         .Named("age")
                                                         .Integer
                                )
                                .AddColumn(column => column
                                                         .Named("username")
                                                         .Varchar
                                )

編集 あなたの場合、次のようなものがあります:

public class FluentMatcher<T1, T2, TResult>
{
    /*
       Methods A B C

     */

    public FluentMatcherWithElse<T1, T2, TResult> Else(TResult resultIfElseRequired)
    {
        return new FluentMatcherWithElse(resultIfElseRequired);
    }
}

public class FluentMatcherWithElse<T1, T2, TResult>
{
    internal FluentMatcherWithElse(TResult resultIfElseRequired) { ... }

    /*
       Methods A B C - but NO else method

     */
}
于 2013-11-06T14:53:28.793 に答える