今天的篇幅应该会很长,除了回顾前面学的一些,还有写一些关于匿名类型的相关知识,总体上对后续的学习很有帮助,学好了,后面更容易理解,不明白的,那就前面多翻几次,看多了总是会理解的。那么,进入正题吧。

  • 自动实现属性

  我们的很多工作都是由编译器帮我们去完成,如我们要说的自动实现属性。使用自动实现属性时,C#3执行了一个简单的编译转换,在类的内部生成一个私有的字段,使用不友好的命名(防止命名冲突)。在C#2中允许为取值和赋值方法指定不同的访问权限,现在我们还可以创建静态的自动属性。

  • 隐式类型

  使用隐式类型,在编写代码时,没有显式地声明类型,但在编译的结果中,编译器会获取初始化表达式的类型,使用变量也具有该类型。隐式类型只有在以下几种情况才能使用:

  1. 被声明的变量是一个局部变量,而不是一个静态字段和实例字段
  2. 变量声明的同时需要初始化
  3. 初始化表达式不能是方法组,也不是匿名函数
  4. 初始化表达式不是null
  5. 语句中只声明了一个变量
  6. 初始化表达式不能包含正在使用的变量
  • 初始化

  一种方法是使用无参的构造函数先实例化一个对象,然后分别为每个公开的属性赋值。另一种则是在构造函数中将属性值作为参数,在构造函数中为每个属性赋值,这里可以给公开和私有的赋值。使用自动实现属性,则可以使用对象初始化器,如下,三个类Computer、Mouse、User

 class Computer
{
public string Cpu { get; set; }
public Mouse Mouse { get; set; }
public List<User> Users { get; set; }
}
class Mouse
{
public string Brand { get; set; }
}
class User
{
public string Name { get; set; }
}

  上述三个类都没有构造函数(有一个默认的无参构造函数),使用对象初始化器就能很方便的去实例化对象。

 Computer c = new Computer()
{
Cpu = "AMD",
Mouse = new Mouse() { Brand = "罗技" },
Users = new List<User> {
new User() {Name="小A" },
new User() {Name="小B" },
new User() {Name="小C" }
}
};

  可以看到上述的每一个对象实例都使用了对象初始器来实例化对象,调用的构造函数都是系统默认的构造函数,当我们将无参的构造函数设置为私有时,上述语句将无效。那我们就可以想像,当有一个为Cup赋值的构造函数,则在new Computer(cupName)接大括号"{}"来初始化对象,如

 class Computer
{
public string Cpu { get; set; }
public Mouse Mouse { get; set; }
public List<User> Users { get; set; }
public Computer(string cpu) {
this.Cpu = cpu;
}
public Computer()
{ }
} Computer c1 = new Computer("AMD")
{
Mouse = new Mouse() { Brand = "罗技" },
Users = new List<User> {
new User() {Name="小A" },
new User() {Name="小B" },
new User() {Name="小C" }
}
};

  注:调用无参的构造函数时,使用省略类名后面的括号。

  是不是看上面的代码不断是很多,那我们可以再精简一下new List<User>,和new Mouse。

  Computer c1 = new Computer("AMD")
{
Mouse = { Brand = "罗技" },
Users = {
new User() {Name="小A" },
new User() {Name="小B" },
new User() {Name="小C" }
}
};

  我们直接将类型名称给去除了,看到这里是否也想到可以把new User也给去除了,不过我试过是不行的,应该是无法确定要转换的类型吧。这个有点类似在C++11中统一使用"{}"来初始化对象。关于集合初始化可以参照上述中的对属性Users的初始化,而上述中Mouse = { Brand = "罗技" }则称呼为初始化嵌入对象。

  • 隐式类型的数组

  在C#1和C#2中,数组的声明和初始化如下

 string[] names = { "a", "b", "c" };

  如果一个方法的签名如下:

 public void Method0(string[] names)

  那使用大括号中的表达式不能作为参数传入该方法,如

 Method0({ "a", "b", "c" });

  必须要告诉编译器传入的数组是什么类型的数组,如

 Method0(new string[] { "a", "b", "c" });

  但如果我们显式的指定类型,可以让编译器自己推断,则用到了隐式类型数组,里面也有涉及到协变性,如果A继承于B,参数为A的数组,那么我们使用隐式类型的数组,就可以传入A实例和B实例的数组。如:

 class A
{
} class B : A
{
} public static void Method1(A[] args)
{ } A a = new A();
B b = new B();
Method1(new[] { a, b });
Method1(new[] { new A(), new B() });
  • 匿名类型

  匿名类型常用作用于LINQ中返回一系列的没有具体类型名的对象,也可以使用单独使用(在不想创建多余的类时)。

 var p = new { Name = "a", Age =  };

  接下来,就可以使用变量p,p有两个属性Name="a"和Age=12,也可以使用匿名类型来初始化数组,如

 var ps = new[] {
new { Name = "a", Age = },
new { Name = "a", Age = },
new { Name = "a", Age = }
};

  匿名类型包含以下成员:

  1. 一个获取所有初始值的构造函数
  2. 公有的只读属性
  3. 属性的私有字段
  4. 重写了由object中继承的方法

  关于投影初始化程序,简单地理解从一个集合中,抽取集合元素中的各别属性,组成一个匿名类型,从而返回一个包含匿名类型的集合,这也是为什么我们使用var关键字,因为我们真的不知道返回的类型,使用var让编译器替我们理解返回类型,那问题来了,这个匿名类型的声明是否由编译器帮我们生成?它帮我们生成了类型,使用反编译工具就能知晓。

  请斧正。

15.C#回顾及匿名类型(八章8.1-8.5)的更多相关文章

  1. C#:匿名类型

    匿名类型和var关键字是Visual C# 3.0提供的一个新特性,var是隐式类型而并不是类型javascript中的var. var user = new { Id = 1, Name = &qu ...

  2. C#3.0新特性:隐式类型、扩展方法、自动实现属性,对象/集合初始值设定、匿名类型、Lambda,Linq,表达式树、可选参数与命名参数

    一.隐式类型var 从 Visual C# 3.0 开始,在方法范围中声明的变量可以具有隐式类型var.隐式类型可以替代任何类型,编译器自动推断类型. 1.var类型的局部变量必须赋予初始值,包括匿名 ...

  3. c# 把一个匿名对象赋值给一个Object类型的变量后,怎么取这个变量? c# dynamic动态类型和匿名类 详解C# 匿名对象(匿名类型)、var、动态类型 dynamic 深入浅析C#中的var和dynamic

    比如有一个匿名对象,var  result =......Select( a=>new {  id=a.id, name=a.name});然后Object  obj =  result ;我怎 ...

  4. Entity Framework 6 Recipes 2nd Edition(11-5)译 -> 从”模型定义”函数返回一个匿名类型

    11-5. 从”模型定义”函数返回一个匿名类型 问题 想创建一个返回一个匿名类型的”模型定义”函数 解决方案 假设已有游客(Visitor) 预订(reservation)房间(hotel ) 的模型 ...

  5. Javascript基础回顾 之(一) 类型

    本来是要继续由浅入深表达式系列最后一篇的,但是最近团队突然就忙起来了,从来没有过的忙!不过喜欢表达式的朋友请放心,已经在写了:) 在工作当中发现大家对Javascript的一些基本原理普遍存在这里或者 ...

  6. Linq专题之提高编码效率—— 第二篇 神一样的匿名类型

    说起匿名类型,我们都知道这玩意都是为linq而生,而且匿名类型给我们带来的便利性大家在实战中应该都体会到了,特别适合于一次性使用,临时 使用这些场景,虽然说是匿名类型,也就是说是有类型的,只是匿名了而 ...

  7. 《精通C#》自定义类型转化-扩展方法-匿名类型-指针类型(11.3-11.6)

    1.类型转化在C#中有很多,常用的是int类型转string等,这些都有微软给我们定义好的,我们需要的时候直接调用就是了,这是值类型中的转化,有时候我们还会需要类类型(包括结构struct)的转化,还 ...

  8. 当匿名类型遇上Distinct

    首先定义一个简单类,并重写ToString方法. public class CommidityFilter { public string Property { get; set; } public ...

  9. C#简单问题,不简单的原理:不能局部定义自定义类型(不含匿名类型)

    今天在进行代码测试时发现,尝试在一个方法中定义一个委托,注意是定义一个委托,而不是声明一个委托变量,在编写的时候没有报错,VS也能智能提示,但在编译时却报语法不完整,缺少方括号,但实际查询并没有缺少, ...

随机推荐

  1. 05_最长公共子序列问题(LCS)

    问题来源:刘汝佳<算法竞赛入门经典--训练指南> P60 问题7: 问题描述:给两个子序列A和B,求长度最大的公共子序列.比如1,5,2,6,8,和2,3,5,6,9,8,4的最长公共子序 ...

  2. Hive DDL DML SQL操作

    工作中经常要用到的一些东西,一直没整理,用的多的记住了,用的不多的每次都是去查,所以记录一下. DDL(数据定义语言),那就包括建表,修改表结构等等了 建表:create hive table hiv ...

  3. Error querying database. Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for …

    编译通过并且运行web成功后,访问的页面不需要连接数据库,不牵扯到反射调用实体类就不会报错, 报错内容如下: [WARNING] org.springframework.web.util.Nested ...

  4. Android 系统架构

    Android 系统从下至上分为四层:Linux 内核.Android 核心库及Android 运行时环境(Android Runtime). 应用程序框架以及应用程序等. Linux 内核(Linu ...

  5. [转]JQuery Ajax 在asp.net中使用总结

    本文转自:http://www.cnblogs.com/acles/articles/2385648.html 自从有了JQuery,Ajax的使用变的越来越方便了,但是使用中还是会或多或少的出现一些 ...

  6. java使用HttpClient传输json格式的参数

    最近的一个接口项目,传的参数要求是json,需要特殊处理一下. 重点是这两句话: httpPost.setHeader("Content-Type", "applicat ...

  7. 【MVC 4】2.使用 Razor

    作者:[美]Adam Freeman      来源:<精通ASP.NET MVC 4> Razor 是微软 MVC3 引入的视图引擎的名称,并在MVC 4 中进行了修订.视图引擎处理 A ...

  8. OpenCV 之 数字图像

    1  数字图像 数字图像可看作一个数值矩阵, 其中的每个元素代表一个像素点,如下图所示: 2  存储 M行N列图像的存储位数: b = M * N * k   ( L=2k, l ∈ [0, L-1] ...

  9. 2014 Super Training #6 G Trim the Nails --状态压缩+BFS

    原题: ZOJ 3675 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3675 由m<=20可知,可用一个二进制数表 ...

  10. a 标签中调用js的几种方法

    我们常用的在a标签中有点击事件: 1. a href="javascript:js_method();" 这是我们平台上常用的方法,但是这种方法在传递this等参数的时候很容易出问 ...