15.C#回顾及匿名类型(八章8.1-8.5)

时间:2021-11-01 22:32:10

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

  • 自动实现属性

  我们的很多工作都是由编译器帮我们去完成,如我们要说的自动实现属性。使用自动实现属性时,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&num;:匿名类型

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

  2. C&num;3&period;0新特性&colon;隐式类型、扩展方法、自动实现属性,对象&sol;集合初始值设定、匿名类型、Lambda,Linq,表达式树、可选参数与命名参数

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

  3. c&num; 把一个匿名对象赋值给一个Object类型的变量后,怎么取这个变量? c&num; dynamic动态类型和匿名类 详解C&num; 匿名对象(匿名类型)、var、动态类型 dynamic 深入浅析C&num;中的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)译 -&gt&semi; 从”模型定义”函数返回一个匿名类型

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

  5. Javascript基础回顾 之&lpar;一&rpar; 类型

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

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

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

  7. 《精通C&num;》自定义类型转化-扩展方法-匿名类型-指针类型(11&period;3-11&period;6)

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

  8. 当匿名类型遇上Distinct

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

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

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

随机推荐

  1. JAVA 1&period;1

    1. JASE : J2SE 这个就是我们现在在学的东西,他是一切Java的核心基础 JAME :J2ME : 他是Java的一个微型版,主要用来做移动开发 JAEE :J2EE Java企业版本,主 ...

  2. 100天后 - 100-days-later

    赛斯·高汀(Seth Godin)的博客:  http://sethgodin.typepad.com/seths_blog/2013/04/100-days-later.html 面对着数以千计的图 ...

  3. 基于Eclipse的Go语言可视化开发环境

    http://jingyan.baidu.com/article/d7130635032e2f13fdf475b8.html 基于Eclipse的Go语言可视化开发环境 | 浏览:2924 | 更新: ...

  4. Sublime Text 3关闭自动更新

    Sublime Text 3关闭自动更新 第一步:help->enter license 这有两个: -– BEGIN LICENSE -– Michael Barnes Single User ...

  5. ios Camera学习笔记

    检测设备的摄像头是否可用: - (BOOL) isCameraAvailable{ return [UIImagePickerController isSourceTypeAvailable: UII ...

  6. java获取真实的IP地址工具类

    在实际项目中,有调用微信支付完成支付功能,在微信支付的请求参数中需要传递一个本机的ip地址,java代码运行环境目前为windows10以及centos7. 以下为获取ip地址工具类: package ...

  7. &num;006 C语言大作业学生管理系统第三天

    还差最后两部分 读取文件 恢复删除的学生信息 先学会处理文件的 知识点,再继续跟着视频做这个作业. 应该明天周六能把视频里手把手教的学生管理系统敲完 第二周尽量自己能完成C语言课本最后面那道学生管理系 ...

  8. 【PAT】B1033 旧键盘打字(20 分)

    #include<stdio.h> #include<algorithm> #include<ctype.h> using namespace std; bool ...

  9. 【网络】高性能网络编程--下一个10年,是时候考虑C10M并发问题了

    转载:http://www.52im.net/thread-568-1-1.html 1.前言 在本系列文章的上篇中我们回顾了过云的10年里,高性能网络编程领域著名的C10K问题及其成功的解决方案(上 ...

  10. 调查显示数据分析已取代Web开发成为第一用例

    一项关于Python的开发者调查显示,编程语言现在主要用于数据分析,取代了之前的第一个用例Web开发. 去年秋天,由Python软件基金会和开发人员工具供应商JetBrains进行,2018 Pyth ...