0

私はWinFormsを使用しており、データベースへの変更を保存する前に、使用されているErrorProviderが表示されているコントロールのいずれかでエラーを保持しているかどうかを確認する必要がありました。

私はそれらの間でそれを行うためのいくつかの方法を考え出しました:

  • ControlContainer上の単純なforeachループ:

        foreach (Control c in ctrlcontainer)
        {
            if (epOrderHeader.GetError(c) != string.Empty)
            {
                return true;
            }
        }
        return false;
    
  • リスト拡張メソッドExists(Predicate)の使用:

    return(ctrlcontainer.Exists(c => epOrderHeader.GetError(c)!= string.Empty);

胃からすぐに、2番目が最も速いと予想しましたが、Eqatec Profilerを使用して、foreachループがわずかに速い(私の場合は約1ms)ことを発見しました。これは重要ではありませんが、なぜこれが起こるのか疑問に思います。

コンパイラはこれらのメソッドをどのように変換し、なぜ最初のメソッドが高速なのですか?

4

3 に答える 3

5

次のように実装されているList<T>.Exists呼び出しがあるため、この場合はおそらく1ミリ秒遅くなります。FindIndex

public int FindIndex(int startIndex, int count, Predicate<T> match)
{
    if (startIndex > this._size)
    {
        ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
    }
    if (count < 0 || startIndex > this._size - count)
    {
        ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_Count);
    }
    if (match == null)
    {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
    }
    int num = startIndex + count;
    for (int i = startIndex; i < num; i++)
    {
        if (match(this._items[i]))
        {
            return i;
        }
    }
    return -1;
}

したがって、これは単純なものよりも少し多くなりforeachます。

于 2012-07-27T12:41:29.953 に答える
1

List.Existsメソッドの方が高速であると期待するのはなぜですか?本質的には、手動チェックと同じように機能しますが、追加で行うことの1つは、直接チェックの代わりに述語を使用したチェックです。これには少しパフォーマンスが必要です。

于 2012-07-27T12:43:57.320 に答える
0

SetError内部のコントロールの機能を使用している場合はctrlcontainer、エラーが発生した時期を追跡できます。カスタマイズしたクラスでクラスを拡張するか、クラスErrorProviderの1つにそのプロバイダーを含めて、SetErrorメソッドをオーバーライドできるようにすることをお勧めします。つまり、何もチェックする必要がないため、との比較は関係Existsありforeachません。

于 2012-07-27T12:53:49.233 に答える