如何测试C#变量是否已分配值?

14

我正在尝试编写一个Linq的MinBy扩展方法

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的Min函数回答了一个不同的问题(即最小平方数是多少)

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

在我看来,对于这个问题,IQueryable<>比IEnumerable<>更好。 - Alex
在MSDN上查看它,它是一种允许查询链接的集合类型,非常强大。 - Alex
你不能使用现有的IEnumerable.Min扩展方法吗?- 这允许你传递一个func<T,int>:http://msdn.microsoft.com/en-us/library/bb548864 - Toby Couchman
很好的问题,托比。我在原始问题中写了一个我想要的行为澄清。 - Colonel Panic
5个回答

27

你需要一个像这样的min默认值:

T min = default(T);

你可以在MSDN上了解更多关于default()的内容:

给定参数化类型T的变量t,如果T是引用类型,则语句t = null仅在t = 0对于数值值类型但不适用于结构时有效。解决方案是使用default关键字,它将为引用类型返回null并为数值值类型返回零。对于结构,它将返回结构的每个成员初始化为零或null,具体取决于它们是值类型还是引用类型。对于可空值类型,默认值返回System.Nullable,其像任何结构一样初始化。


谢谢。这会破坏我的逻辑吗?经过一点思考,不会。 - Colonel Panic

4
min添加默认值:
T min = default(T);

它抱怨的原因是编译器无法验证在 return min; 行中使用 min 之前是否已经为其分配了一个值。未分配的局部变量不能被引用,因此编译器会生成一个错误。

1

这是因为min在条件语句内被赋值。编译器无法确定它是否会得到一个值,所以你应该用默认值初始化min。


0

不能测试变量是否被赋值,否则会始终得到编译错误。


-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;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接