2012-03-28 11 views
5

私は多くのコードを持っています。を初期化中に実行する必要があります。ブールでヒューズを行う

それはイベントで

bool _fuse; 

void PerformLayout() 
{ 
    Size size; 

    if (!_fuse) 
    { 
     size = _InitialContainerSize; 
     _fuse = true; 
    } 
    else 
     size = parent.Size; 

    // ... 
} 

あるので、私はそれが頻繁に起こるので、私はヒューズのように見えるように、このブール変数を作るために何かをしたブールフラグをこの方法を使用する必要があります。

は、だから私はこれをしなかった:

bool _fuse; 

void PerformLayout() 
{ 
    Size size; 

    if (!Burnt(ref _fuse)) 
     size = _InitialContainerSize; 
    else 
     size = parent.Size; 

    // ... 
} 

falseに初期化されている場合、クエリの結果は一度falseを返し、switcを作りますhをtrueに設定し、連続する呼び出しはtrueを返します。

public static bool Burnt(ref bool value) 
{ 
    if (!value) 
    { 
     value = true; 
     return false; 
    } 
    else 
     return true; 
} 

もちろん、動作しますが、私は中程度に満足しています。より洗練されたソリューションがあると確信しています。あなたのことは何ですか?

Size? _containerSize; 

Size ContainerSize { 
    get { 
    return (_containerSize ?? (_containerSize = _InitialContainerSize)).Value; 
    } 
} 

あなたは、このようにそれを使用することができます:

void PerformLayout() { 
    var size = ContainerSize; 
    // ... 
} 

タイプあなたは怠惰な初期化したい場合は

+2

'戻り値|| !(値=真); '(ちょうど冗談!) –

+0

面白い。今のところ、3つのアップフォースと3つの投票が終了しています。 –

+0

本当の質問ではありません。 codereviewサイトにある必要があります。ここにはない。 – leppie

答えて

1

私はまだここに繰り返しを回避する上での一般的な推力は...の繰り返しが非常に小さい場合であっても(正しいと思うけど)。ちょうどそれをカプセル化し、それを正しく名前:

struct InitializerGuard { 
    private bool hasRun; 

    public bool HasRun() { 
     if (hasRun) 
      return true; 
     hasRun = true; 
     return false; 
    } 
} 

使用法:

InitializerGuard sizeInitializer; 

void PerformLayout() 
{ 
    Size size; 

    if (!sizeInitializer.HasRun()) 
     size = _InitialContainerSize; 
    else 
     size = parent.Size; 

    // ... 
} 

をしかし、あなたは非常に頻繁にこのパターンを使用して自分自身を見つけた場合、これはリファクタリングが順序であることを示している可能性があります。たぶん、いくつかの変数にデフォルト値を割り当てるだけでしょうか?とにかく彼らはなぜ初期化されないのですか?

+1

または単に:Size size = HasRun()? parent.Size:_initSize; ' – leppie

+0

これはエレガントでクリアです。私はそれが好きです。私はこれをコピーするつもりだと思う。 (おそらく私はHasRunメソッドを代わりにプロパティに変更するだろうか?) - 私はpropably私のコードのいくつかの部分をリファクタリングすることができますが、多くの場合、いくつかのイベントで使用されているため選択肢がありません。最初の火。 – Larry

+1

@Laurentプロパティには副作用があってはいけません。少なくとも、これはあなたのデバッガをねじ込みます(コードをデバッグし、この変数のウォッチを追加すると、プロパティは任意のタイミングで評価され、動作が変わります)。したがって、これをプロパティにすると、コードが「面白い」方法で破損します。 ;-) –

1

あなたはSizeプロパティを宣言するためにNULL値可能なタイプとnull合体演算子を使用することができます参照型であっても、より単純になります。

もう1つの方法は、Lazy<T>タイプを使用することです。これは、上記のコードが破損する可能性のあるマルチスレッドシナリオで使用できます。

1

これを達成する方法は数多くあります。ロジックを実行する複雑なステートマシンを作成することはできますが(最速)、多くの場合、それは過剰です。代わりに、今のようにインスタンスの状態を保持するブール値を追跡することができます。また、(moderatly速い)のような方法で、簡単なステートマシンに両方のソリューションを組み合わせることを決定することができます

public class TestClass 
{ 
    private Action performLayoutAction; 

    public TestClass() 
    { 
     // initial state 
     performLayoutAction = InitializePeformLayout; 
    } 

    public void PerformLayout() 
    { 
     performLayoutAction(); 
    } 

    private void InitializePeformLayout() 
    { 
     // whatever 

     performLayoutAction = ContiniousPerformLayout; 
    } 

    private void ContiniousPerformLayout() 
    { 
     // whatever 
    } 
} 
関連する問題