2

为什么这个简单的代码不起作用?

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

我期望像零数组但得到编译器错误。那么我如何在 lambda 表达式中使用默认值呢?

在我的实际应用程序中,我有类型为 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[]所有值为零的。

编辑:现在我们有了更多信息,更容易提供你想要的东西,这基本上是一种从 a 获取默认值的方法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(根据问题, a在哪里FieldInfo- 我故意不在这里打电话GetType()。)

于 2013-03-03T20:37:41.213 回答
3

您无法通过这种方式在运行时获取默认值,default()并且typeof()是编译时功能。但是你可以试试这个建议。它用于Activator.CreateInstance在运行时获取值类型的默认值。

于 2013-03-03T20:39:52.477 回答
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 回答
2

编译器需要一个编译时类型:

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

将生成全 0。不过,我不知道你想用这个实现什么,因为所有这些都是返回一个具有默认值的空数组。

于 2013-03-03T20:38:48.910 回答