C#中的匿名类型与隐式类型变量

    在C#3.0中引入了Linq,使得对集合的操纵发生了深刻的变化,这个变化的幕后英雄便是扩展方法和匿名类型。这里我们谈一谈C#中的匿名类型与隐式类型变量。

一、匿名类型

      所谓匿名类型顾名思义就是没有类型名称的一种特殊的数据类型,这意味着我们不能显式的引用这种类型的名称。事实上它是由编译器在后台声明并帮你生成必要的代码。

   

代码
class Program
{
public static void Main(string[] args)
{
var T1
= new {Index = 10,Name = "CPU",Price = 200.0};
var T2
= new {Index = 20,Name = "MethodBoard",Price = 499.0};
var T3
= new {T1.Index, Name = "SoundCard",Price = 210.0};

}
}

 

 

     以上我们用var 声明了3个隐式类型的变量T1,T2,T3,并把创建(new)的3个匿名类型的实例分别赋给它们。在这里var相当于一个占位符,其变量(T1,T2,T3)的具体的类型是在代码编译时确定的,也就是说由赋给它们的值的数据类型而定的。因而在最终生成的CIL中T1,T2,T3是有具体的类型的,也就是强类型的

 

    在上例中,我们可以看到T3中使用了T1的属性Index,这说明匿名类型的属性是完全可以访问的。它们使用了相同的属性名称,属性的数据类型也相同,并且属性的的顺序也是一致的,因而它们具有相同的类型,否则就不是兼容的类型了。

   

    如以下均不是相同的类型了,其中T4与T5的属性不同,T4与T6的属性顺序不一样。

 

var T4 = new {Index = 10,Name = "CPU",Price = 200.0};
var T5
= new {Index = 20,Title = "MethodBoard",Price = 499.0};
var T6
= new {T1.Index, Price = 210.0, Name = "SoundCard" };

 

  匿名类型是“不可变”的,也就是说匿名类型的实例是不能够更改它的属性的,否则会造成编译错误,如:

 

var T4 = new {Index = 10,Name = "CPU",Price = 200.0};
T4.Index = 11;//引发编译错误

 

 

二、隐式类型变量

    隐式类型变量是用var关键字声明的局部变量,这个变量的具体类型是可以通过赋傎号右边的表达式推导出来的。其实在大多数情况下,隐式类型变量都是为匿名类型的实例而存在的。

 

    隐式类型变量只能用于以下的场合:

   1. 局部变量声明

   2. for、foreach 语句中变量声明

   3. using 语句初始化变量

    尤其要注意的是不能在类的字段中或方法的参数中使有隐式类型。

 

    那么问题是有没有办法在创建匿名类型的方法内部,将其实例传到方法的外部呢?答案是肯定的,主要有两种方法:

  1.利用object参数,因为隐式类型变量可以自动转换为objcet。

public void OutVarInstance1(out object obj)//把匿名类型的实例传到方法外1:使用object
{
var v1
= new
{
Name
= "ZYS",
Type
= "CEO"
};
obj
=v1;
}

 

    在这里隐式类型变量可以自动的转换为object类型。当然对于调用者而言其操作仅限于object支持的那些。

 

   2.利用方法类型推导,匿名类型的实例以一个方法的“类型参数”的形式来传递,编译器可以推导出具体的类型。

 

代码
public void OutVarInstance2()//把匿名类型的实例传到方法外2:使用"类型参数"
{
var v2
= new {Title = "2222",Text = "Ok"};
Method(v2);
}


public void Method<T>(T input)
{
Console.WriteLine(
string.Format("Text out {0}",input));
}

 

  现在在Method中我们就可以对匿名类型的实例进行访问了。

 

 

 

 

 

 

 

 

posted @ 2010-07-29 19:13  行之者  阅读(453)  评论(0编辑  收藏  举报