65.9K
CodeProject 正在变化。 阅读更多。
Home

一点 var 的爱

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.43/5 (3投票s)

2009年6月17日

CPOL

2分钟阅读

viewsIcon

12772

一点 var 的爱

如我们所知,LINQ 赋予我们的一项功能是匿名类型,这些类型可以通过使用选择查询运算符来使用,例如:

   1:  var x = new { DateNow = DateTime.Now };

这将给我们一个带有单个 DateTime 属性的匿名类型,该属性名为“DateNow”,这非常好。这很大程度上归功于“var”关键字。

如果你花时间使用“var”关键字,你很快就会意识到,你无法在当前方法的作用域之外,将声明为“var”的对象作为强类型对象来使用。

我们可以通过将对象类型作为参数来规避这个问题,在可以传递匿名参数的地方使用它。这在下面的屏幕截图中得到了演示。正如我们所见,我们可以传递一个匿名类型,但从那里开始,我们得到的是一个对象类型,因此获取值的唯一方法是使用反射。

37319/image-thumb.png

这里有一个例子,展示了我们可以很好地获取匿名类型的值。

37319/image-thumb1.png

匿名类型不能用作方法结果,除非该方法返回类型为 object。这就是为什么匿名类型应该只在方法内部局部使用的原因。一个打破这个规则的地方是在泛型方法中。

考虑以下示例代码:

   1:          /// <summary>
   2:          /// Simple generic method
   3:          /// </summary>
   4:          public static TResult 
   5:              HaveSomeGenericFun<TResult>(Func<TResult> input)
   6:          {
   7:              return input();
   8:          }
   9:   
  10:          static void Main(string[] args)
  11:          {
  12:              //I am calling a generic method here passing it an 
  13:              //anonomous type….curious
  14:              var obj = HaveSomeGenericFun(
  15:                  () => new 
  16:                      {   
  17:                          Time = DateTime.Now, 
  18:                          ProcessName = 
  19:                              Process.GetCurrentProcess().ProcessName 
  20:                      });
  21:   
  22:              Console.WriteLine(String.Format(
  23:                  “Process {0} was running at {1}”, 
  24:                  obj.Time, obj.ProcessName));
  25:   
  26:              Console.ReadLine();
  27:          }

HaveSomeGenericFun 的返回类型是泛型的。如果我们不指定 TResult 的类型来调用它,它将从“input”参数的签名中自动推断出来。由于提供的参数“inputFunc<TResult> 返回一个匿名类型的实例,因此 HaveSomeGenericFun() 泛型方法将返回该类型。

正如所见,HaveSomeGenericFun() 方法没有在任何地方使用对象返回值,因此返回值将是强类型的。

虽然这很好,但总的来说用处不大,LINQ 内部使用了这种机制,我觉得这很有趣,所以值得一提。

好了,就说到这里吧,考虑一下已经提到了。

© . All rights reserved.