隐式键入局部变量'var'到隐式类型的局部变量

时间:2013-09-05 08:45:51

标签: c# var implicit

假设我有一个相当复杂的表达式,使用此表达式作为示例,我想用显式变量替换var?

var collection = Enumerable.Range(0, 10)
   .Where(x => x % 2 != 0)
   .Reverse()
   .Select(x => new { 
                       original = x, 
                       sqrt = Math.Sqrt(x) 
                    });

我已经尝试了很多组合来替换var,但它不会一直给我一个错误。哦,VS告诉我它没有真正帮助的类型......

E.g。我试过替换

var collection

IEnumerable<KeyValuePair<int, double>> collection

4 个答案:

答案 0 :(得分:4)

因为您选择的是new对象,所以结果是Anonymous Type,而那些您无法用该类型代替var。

答案 1 :(得分:2)

如果你真的想在那里放东西,你可以使用

IEnumerable<dynamic> collection = Enumerable.Range(0, 10).Where(x => x % 2 != 0)
      .Reverse()
      .Select(x => new { original = x, sqrt = Math.Sqrt(x) });

你不能做更多的事情,因为你在表达式中创建了一个匿名对象。

请阅读Jeppe Stig Nielsen的评论,详细解释为什么即使可以,也不应该这样做。

答案 2 :(得分:1)

你可能想要这样的东西

IEnumerable<KeyValuePair<int, double>> collection = 
        Enumerable.Range(0, 10)
                  .Where(x => x%2 != 0)
                  .Reverse()
                  .Select(x => new KeyValuePair<int, double> (x,Math.Sqrt(x)));

答案 3 :(得分:0)

我认为最干净的方法是将您的匿名类型转换为显式声明的类:

public static void Main(string[] args)
{
    IEnumerable<WithRoot> collection = Enumerable.Range(0, 10)
       .Where(x => x % 2 != 0)
       .Reverse()
       .Select(x => new WithRoot(x, Math.Sqrt(x)));    
}

private sealed class WithRoot
{
    public WithRoot(int orig, double root)
    {
        this.Original = orig;
        this.SquareRoot = root;
    }

    public int Original { get; private set; }

    public double SquareRoot { get; private set; }
}

这使您可以在代码中命名类型,同时保持完全类型安全(与使用dynamicobject的解决方案相比)。但是,它会使您的代码更加冗长。坦率地说,我怀疑你是否需要它,我不鼓励你这样做只是为了明确打字。 var并非坏/坏。

功能差异:请注意,我的代码示例中EqualsGetHashCode 未被覆盖。当您使用匿名类型时,这也会自动发生。