2017-10-23 9 views
0
protected IteratorAdvance<int> Advance; 

public delegate void IteratorAdvance<T2>(out T2 itemIndex); 

public IteratorBase() 
{ 
    Advance = delegate(out int i) { i++; }; // <--- here 
} 

上記は、さまざまな種類のループのラッパーであるクラスのスニペットです。以下のコンストラクタのオーバーロードでは、インスタンス化者は、forループを継続する条件が決定される方法と、各繰り返しでそのループの制御値がどのように変更されるかを指定できます。C# - デリゲートアクションのoutパラメーターの既定値の設定

これは、データソースの最後のインデックスに達するまで0から始まり、1ずつインクリメントすることが最も簡単で最も可能性が高いことは明らかです。私は、デフォルトの方法と効果的に(この場合の非常に複雑なバージョン)です初期値を提供してきましたそのため

for(var i = 0; i < list.Count; i++) 

ためにここにコンストラクタです:

public IteratorBase(IterationStyle style, Func<int, T1, bool> complete, IteratorAdvance<int> advance, bool onErrorAbort = true, int initialValue = 0) 
{ 
    Style = style; 
    InitialValue = initialValue; 
    Complete = complete; 
    Advance = advance; 
    AbortOnError = onErrorAbort; 
} 

どこに問題がありますコントロールの値をインクリメントすると、コンパイラはそのスコープで宣言されている変数(i)のデフォルト値を要求し、outパラメータであるためデフォルト値を受け入れることができません。

機能の本体を別のメソッドに移動しても、同じ問題が存在します。私はそれを初期化するforループ自体の前にoutパラメータを初期化することはできません。

case IterationStyle.For: 
    for (controlValue = InitialValue; !Complete(controlValue, item); Advance(out controlValue)) 
    { 
     action.TargetItem = item = dataSource[controlValue]; 
     if (!ActWrapper(action)) 
      return false; 
    } 
    break; 

私は考えることができる唯一のソリューションは、唯一の方法への外部ブールのいくつかの種類を使用して関与するメソッドの最初の呼び出しでoutパラメータをintialiseすることです。私はそのようなことを避けるために私が一人でいるとは思わない。そしてそれはどちらもうまくいかないので、コントロール値をグローバルにする必要があります。私の死体で

通常、この種の状況では、あなたのアプローチが間違っていることを意味します。しかし、私は別の方法を考えることはできません。私はあなたができることを望んでいます。それとも、私がoutパラメータを初期化するか、デフォルト値を与える方法を教えてください。

+0

いいえ、それは役に立たなかった。答えは簡単です。私はrefを使わないでください。 D'oh! – twelveFunKeys

+0

Ah、ref。はい。私はそれを提案しようとしていた:) – David

答えて

2

他の誰かが頭がおかしくなってしまった場合に備えて、ここに解決策があります。 refではなくoutを使用してください。

Advance = delegate(ref int i) { i++; }; 
関連する問題