2

この単純なコードが機能しないのはなぜですか?

var abc = new[]{1,2,3,4}.Select(x => default(typeof(x)));

ゼロの配列のようなものを期待していますが、コンパイラ エラーが発生します。では、ラムダ式でデフォルト値を設定するにはどうすればよいですか?

私の実際のアプリケーションでは、タイプ Type のメタクラスがあります

public class FieldInfo
{
     public Type type
}

メソッドのパラメータとして取得IEnumerable<FieldInfo>し、各タイプのデフォルト値の配列を返したい ( object[])

4

4 に答える 4

6

これが問題です:

typeof(x)

typeof値を取得するメソッド呼び出しであるかのように演算子を使用しています。そうではありません。コンパイル時の型名または型パラメーター (またはDictionary<,>、 またはなどのバインドされていない型) が必要voidです。

同じことがdefault演算子で試行されます。

それが問題なのですが、何を達成しようとしているのかを知らなければ、実際に修正方法をアドバイスすることはできません. 次のようなものが必要な場合があります。

public static IEnumerable<T> SelectDefault<T>(this IEnumerable<T> source)
{
    return source.Select(x => default(T));
}

次に、これ:

var abc = new[]{1,2,3,4}.SelectDefault().ToArray();

...int[]すべての値がゼロになります。

編集:これで、より多くの情報が得られました。必要なものを提供するのが簡単になりました。これは、基本的に、Type必要に応じてボックス化からデフォルト値を取得する方法です。

public static object GetDefaultValue(Type type)
{
    // Non-nullable value types should be boxed, basically
    if (type.IsValueType && Nullable.GetUnderlyingType(type) == null)
    {
        // Not the swiftest approach in the world, but it works...
        return Activator.CreateInstance(type);
    }

    // Everything else defaults to null
    return null;
}

したがって、次のようになります。

var defaults = fields.Select(field => GetDefaultValue(field.type));

(質問によるとどこfieldにありますFieldInfoか-私は意図的にここに電話していませんGetType()。)

于 2013-03-03T20:37:41.213 に答える
3

これのことですか?

var abc = new[]
{
    1, 2, 3, 4
}
.Select(x = > {
    var xType = x.GetType();
    if (xType.IsValueType)
    {
        return Activator.CreateInstance(xType);
    }
    else
    {
        return null;
    }
})
于 2013-03-03T20:46:33.400 に答える
3

この方法では実行時にデフォルト値を取得できず、default()コンパイルtypeof()時の機能です。しかし、この提案を試すことができます。Activator.CreateInstance実行時に値型のデフォルト値を取得するために使用します。

于 2013-03-03T20:39:52.477 に答える
2

コンパイラにはコンパイル時の型が必要です。

var abc = new[]{1,2,3,4}.Select(x => default(Int32));

すべて 0 を生成します。ただし、これで何を達成しようとしているのかはわかりません。これは、デフォルト値を持つ空の配列を返すだけだからです。

于 2013-03-03T20:38:48.910 に答える