一、隐式类型var
从 Visual C# 3.0 开始,在方法范围中声明的变量可以具有隐式类型var。隐式类型可以替代任何类型,编译器自动推断类型。
1、var类型的局部变量必须赋予初始值,包括匿名类(初始值不能为null)。
var s = ”c#”; var name = new {name=”aa”,age=24};
2、隐式类型的数组
var a = new[]{100};//int[] a=new int[]{1,10,100} var b = new[]{new[]{1,2,3},new[] {4,5,6}}//交错数组也可用new[]初始化,不支持隐式类型的多位数组。
3、var 只能作为局部变量使用,即只能定义在方法内或在属性get、set访问器中。还可用于foreach ,for , using语句中。
public string Name { get { var p = new Person();//正确 return p.Name; } }
for(var i=0;i<10,i++) {} using (var file=new StreamReader(“”) {}
4、var 多数情况在匿名类型和LINQ中使用。
string[] words = { "aa", "bb", "cc" }; var upperLower = from w in words select new { Upper = w.ToUpper(), Lower = w.ToLower() }; foreach (var word in upperLower) { Console.WriteLine(word.Upper+","+ word.Lower); }
二 、对象/集合初始值设定项
1、对象初始值设定项
可以在创建对象时向对象的可访问字段或属性赋值,而无需显示调用构造函数。从 C# 6 开始,除了分配字段和属性外,对象初始值设定项还可以设置索引器。
例1:简单应用
public class Cat { public string name { set; get; } public int age { get; set; } } void Main() { //老式 Cat x = new Cat(); x.name = "aa"; x.age = 1; //对象初始值设定项 Cat x1 = new Cat { name = "aa", age = 1 }; Console.Write(x1.age); }
例2:嵌套应用
class Rectangle { public Point P1 { set; get; } public Point P2 { set; get; } public Rectangle() { P1 = new Point(); P2 = new Point(); } }
void Main() { Rectangle myRec = new Rectangle { P1 = new Point() { X = 1, Y = 1 }, P2 = new Point() { X = 200, Y = 200 } }; Console.Write(myRec.P2.Y); }
2、集合初始值设定项
无需再代码中指定对该集合类的多个Add方法调用,编译器自动添加调用。
集合类必须实现IEumerable。
例1:
List<int> list=new List<int> {0,1,2,3};
例2:
Lista = new List { new Rectangle {P1 = { X = 1, y = 1 },P2 = { X = 200, y = 200 }, new Rectangle {P1 = { X = 1, y = 1 },P2 = { X = 200, y = 200 } } //如果Add方法允许,可以将null指定为其中的一个元素
例3、如果集合支持读取/写入索引,可以指定索引元素。
var numbers = new Dictionary<int, string> { [7] = "seven", [9] = "nine", [13] = "thirteen" };
注意:前面的示例生成调用 Item[TKey] 以设置值的代码。 从 C# 6 开始,可以使用以下语法初始化字典和其他关联容器。 它使用具有多个值的对象,此初始值设定项示例调用 Add(TKey, TValue),将这三个项添加到字典中。
var moreNumbers = new Dictionary<int, string> { {19, "nineteen" }, {23, "twenty-three" }, {42, "forty-two" } };
由于编译器生成的方法调用不同,这两种初始化关联集合的不同方法的行为略有不同。 这两种变量都适用于 Dictionary
类。 其他类型根据它们的公共 API 可能只支持两者中的一种。
三、匿名类型
匿名类型是编译器动态创建的一个类,用于存储一组值。
要创建匿名类型,请使用new关键字和对象初始化器,指定类型将包含的属性和值。
可以将一组只读属性封装到单个对象中,无需首先定义一个类型。匿名类型只能用于定义它的方法中。
匿名类型由一个或多个公共只读属性组成。成员不能用null赋初值。如果多个匿名类型有相同数量和种类的属性,编译器将视为相同的类型,生成多个实例。
var noName = new { name = "a",
age = 1 }; Console.Write(noName.name);
1、匿名类型的属性名称可以从表达式中推断出来:
int Age = 3; var person = new { Name = "Jack", Age, Age.ToString().Length };
相当于:
var person = new { Name = "Jack", Age = Age, Length = Age.ToString().Length };
2、由匿名类型构成的数组
var anonArray = new[] { new { name = "apple", diam = 4 },
new { name = "grape", diam = 1 }};
生成匿名类型数组
var result = new { pages = 10, Users = from mo in list select new { id = mo.UserId, name = mo.Nick } };
可以生成:
var result = new { pages = 10, users = new[]{ new{id=1,name="2"} new{id=2,name="3"} } }
3、由匿名类型构成的列表和字典
var a1 = new List<dynamic>() { new { X = 100, Y = 200 }, new { X = 300, Y = 400} }; Console.Write(a1[1].X); var moreNumbers = new Dictionary<dynamic, dynamic> { {19, "nineteen" }, {23, "twenty-three" }, {42, "forty-two" } }; Console.Write(moreNumbers[19]);
4、在Linq 中使用
匿名类型通常用在查询表达式的 Select 子句中,以便返回原序列中每个对象的属性子集(Linq 中使用的比较多)。
class MyClass { public string Name { set; get; } public int Number { set; get; } } void Main() { MyClass[] list = new MyClass[12]; var varbj = from obj in list select new { obj.Name,
ID=obj.Number}; foreach (var v in varbj) { Console.Writ(v.Name, v.ID); } }
5、应用
匿名类型对象的传递
void Main() { //匿名类型 var news = new { title = "冰红茶", day = "2019-4-10", author = "康师傅" }; ShowInfo(news); } static void ShowInfo<T>(T news) { dynamic d = news; Console.WriteLine(d.title); Console.WriteLine(d.day); Console.WriteLine(d.author); }
用匿名类型填充数组,并计算总年龄
var family = new[] //使用隐式类型的数组初始化程序 { new { Name = "Holly", Age = 37 }, //同一个匿名类型连用5次 new { Name = "Jon", Age = 36 }, new { Name = "Tom", Age = 9 }, new { Name = "Robin", Age = 6 }, new { Name = "William", Age = 6 } }; int totalAge = 0; foreach (var person in family) //totalAge累加 对每个人使用 { totalAge += person.Age; } Console.WriteLine("Total age: {0}", totalAge);