2

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

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

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

例如,我尝试更换

var collection

IEnumerable<KeyValuePair<int, double>> collection
4

4 回答 4

4

因为您正在选择一个new对象,所以结果是Anonymous Type,并且您不能用类型替换 var。

于 2013-09-05T08:48:13.277 回答
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 的评论,详细解释为什么你不应该这样做,即使你可以。

于 2013-09-05T08:48:53.187 回答
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)));
于 2013-09-05T08:54:10.207 回答
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; }
}

这使您能够在代码中命名类型,同时保持完整的类型安全(与使用dynamicor的解决方案相比object)。但是,它会使您的代码更加冗长。坦率地说,我怀疑您是否需要它,并且我不鼓励您仅仅为了显式键入而这样做。var不坏/邪恶。

功能差异:请注意,Equals并且不会在我的代码示例中GetHashCode覆盖。当您使用匿名类型时,这也会自动发生。

于 2013-09-05T08:58:32.760 回答