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を返し、trueに切り替え、後続の呼び出しはtrueを返します。

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

もちろん、それは機能しますが、私は適度に満足しているだけであり、よりエレガントな解決策があると確信しています。あなたは何になりますか?

4

3 に答える 3

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;

    // ...
}

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

于 2012-03-28T09:56:07.053 に答える
1

null 許容型と null 合体演算子を使用して、Sizeプロパティを宣言できます。

Size? _containerSize;

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

その後、次のように使用できます。

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

遅延初期化する型が参照型の場合は、さらに単純になります。

別のオプションは、Lazy<T>タイプを使用することです。これは、上記のコードが壊れる可能性のあるマルチスレッド シナリオで使用できます。

Lazy<Size> _containerSize = new Lazy<Size>(() => _InitialContainerSize);

void PerformLayout() { 
  var size = _containerSize.Value;
  // ...
}
于 2012-03-28T09:36:23.927 に答える
1

これを達成する方法はたくさんあります。ロジックを (最速で) 実行する複雑なステート マシンを作成できますが、多くの場合、それはやり過ぎです。または、現在のようにインスタンスの状態を保持するブール値を追跡することもできます。次のような方法を使用して、両方のソリューションを単純なステート マシンに結合することもできます (適度に高速)。

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 
    }
} 
于 2012-03-28T09:37:30.060 に答える