一、匿名类型概述
匿名类型用‘var’来表示,其好处就是开发人员不需要指定具体的类型,C#将会根据运算符右侧表达式所定义的给出数据类型。换言之,该匿名类型为何种类型交由C#中间编译器来分析,而编译器给出的类型可能是我们熟悉的基础类型,也有可能是我们自定义的类型,甚至是我们未曾定义过的类型。当然,对于简单的类型定义,是无法体现出使用var的优越性的,它的最大价值在于可用它来创建单次使用的元素以及由LINQ查询返回的我们无法轻易定义的复合类型。值得注意的是,由于匿名类型没有属性设置器,因此匿名类型是不可修改的。因此,
两个单独定义的匿名类型,如果它们的各个字段的值、字段顺序、声明顺序、成员数量、成员名称等都相等的话,那么就可以认为它们是相等的。
二、使用匿名类型需要遵守的一些规则
2.1 匿名类型必须有一个初始化值,且该值不能为null,因为编译器需要根据值来推断出一个强类型。
2.2 复合匿名类型需要有成员声明
2.3 数组的初始化器必须使用new关键字
2.4 方法可以返回匿名类型,不过必须转换为object,这不符合强类型原则
注:匿名类型是可以从函数返回的,因为垃圾收集器(GC)会清理任何对象。
2.2 复合匿名类型需要有成员声明
2.3 数组的初始化器必须使用new关键字
2.4 方法可以返回匿名类型,不过必须转换为object,这不符合强类型原则
注:匿名类型是可以从函数返回的,因为垃圾收集器(GC)会清理任何对象。
【示例】
using System;
using System.Reflection;
namespace 给匿名类型添加一个行为
{
class Program
{
static void Main(string[] args)
{
//添加可能的方法
Func<string, string, string> Concat1 = delegate (string first, string last)
{
return first + "," + last;
};
Func<Type, Object, string> Concat2 = delegate (Type t, Object o)
{
//发现属性 (Property) 的属性 (Attribute) 并提供对属性 (Property) 元数据的访问
PropertyInfo[] info = t.GetProperties();
//用索引化属性的可选索引值返回指定对象的该属性值。
//对于非索引化属性,该值应为 null。
Console.WriteLine(info[0].Name+" "+info[1].Name);
return (string)info[0].GetValue(o, null) + "," + (string)info[1].GetValue(o, null);
};
var person1 = new { first = "xu", last = "shuai", Concat = Concat1 };
var person2 = new { first = "zhu", last = "xiao", Concat = Concat2 };
Console.WriteLine(person1.Concat(person1.first, person1.last));
Console.WriteLine(person2.Concat(person2.GetType(), person2));
Console.ReadKey();
}
}
}
分析:上述代码定义了一个匿名委托赋值给泛型类Func。而Concat被定义为一个匿名委托,接收两个参数。此时,可以将这个委托赋值给任何一个被定义为Func实例(即拥有三个字符串类型的形参)的变量。最后,再在该匿名类型定义中将变量Concat赋值给一个成员声明器。这样就可以欢快地调用Concat了。
【示例】
using System;
namespace 从函数返回匿名类型
{
class Program
{
static void Main(string[] args)
{
//由于垃圾收集器会清理任何对象,因此匿名类型自然是可以从函数返回的,不过,此时匿名类型不过是一个
//Object的实例而已。值得注意的是,返回object类型将会使智能感应无效。
var anno = GetAnonymous();
//Type:表示类型声明:类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义,以及开放或封闭构造的泛型类型。
//获取当前实例的Type,返回的类型很可能是我们难以定义的。
Type t = anno.GetType();
Console.WriteLine(t.Name);
var n = 2;
Console.WriteLine(n.GetType());
var s = "dhsjkdhis";
Console.WriteLine(s.GetType());
Console.WriteLine(t.GetProperty("Stock").GetValue(anno, null));//MSTF
Console.ReadKey();
}
public static object GetAnonymous()
{
var stock = new { Stock = "MSTF", Price = "78.56" };
return stock;
}
}
}