14

LinqMinBy拡張メソッドをコーディングしようとしています

public static class Extensions
{
    public static T MinBy<T>(this IEnumerable<T> source, Func<T,int> selector)
    {
        T min;
        int? minKey = null;
        foreach (var x in source)
        {
            var key = selector(x);
            if (minKey == null || key < minKey)
            {
                minKey = key;
                min = x;
            }
        }
        if (minKey == null)
        {
            throw new ArgumentException("source should not be empty");
        }
        return min;
    }
}

私の論理は正しくて読みやすいと思います。しかし、ビルドエラーが発生します

割り当てられていないローカル変数「min」の使用

これについて私は何ができますか?変数が割り当てられているかどうかをテストできますか?


明確化:MinBy関数は次の質問に答えることができます。最小の平方を持つ数字[-5、-2、3]はどれですか?

> new List<int>{-5,-2,3}.MinBy(x => x*x)
-2

.NETの最小関数は別の質問に答えます(これは平方の最小値です)

> new List<int>{-5,-2,3}.Min(x => x*x)
4
4

5 に答える 5

26

min次のようなデフォルト値が必要です。

T min = default(T);

詳細についてdefault()は、MSDN を参照してください。

パラメーター化された型 T の変数 t が与えられた場合、ステートメント t = null は、T が参照型であり、t = 0 が数値型に対してのみ機能し、構造体に対しては機能しない場合にのみ有効です。解決策は、default キーワードを使用することです。これは、参照型に対して null を返し、数値型に対してゼロを返します。構造体の場合、値型か参照型かに応じて、構造体の各メンバーをゼロまたは null に初期化して返します。null 許容値型の場合、default は System.Nullable を返します。これは、構造体と同様に初期化されます。

于 2012-07-04T09:32:24.450 に答える
4

のデフォルト値を追加min:

T min = default(T);

minそれが不平を言っている理由は、行で使用される前に値が割り当てられることをコンパイラが検証できないためですreturn min;。割り当てられていないローカル変数は参照できないため、コンパイラはエラーを生成します。

于 2012-07-04T09:33:31.033 に答える
1

これは、条件内で min が割り当てられているためです。コンパイラは、値を取得するかどうかを判断できません。min をデフォルト値で初期化する必要があります。

于 2012-07-04T09:32:34.817 に答える
0

いいえ、変数が割り当てられているかどうかをテストすることはできません。常にコンパイル エラーが発生します。

于 2012-07-04T10:57:26.527 に答える
-1

参考までに、これは私が最終的に得たものです

    public static T MinBy<T>(this IEnumerable<T> source, Func<T,int> selector)
    {
        T min = default(T);
        bool started = false;
        int minKey = default(int);
        foreach (var x in source)
        {
            var key = selector(x);
            if (!started || key < minKey)
            {
                minKey = key;
                min = x;
                started = true;
            }
        }
        if (!started)
        {
            throw new ArgumentException("source should not be empty","source");
        }
        return min;
    }
于 2012-07-04T09:57:24.660 に答える