今天的篇幅应该会很长,除了回顾前面学的一些,还有写一些关于匿名类型的相关知识,总体上对后续的学习很有帮助,学好了,后面更容易理解,不明白的,那就前面多翻几次,看多了总是会理解的。那么,进入正题吧。
- 自动实现属性
我们的很多工作都是由编译器帮我们去完成,如我们要说的自动实现属性。使用自动实现属性时,C#3执行了一个简单的编译转换,在类的内部生成一个私有的字段,使用不友好的命名(防止命名冲突)。在C#2中允许为取值和赋值方法指定不同的访问权限,现在我们还可以创建静态的自动属性。
- 隐式类型
使用隐式类型,在编写代码时,没有显式地声明类型,但在编译的结果中,编译器会获取初始化表达式的类型,使用变量也具有该类型。隐式类型只有在以下几种情况才能使用:
- 被声明的变量是一个局部变量,而不是一个静态字段和实例字段
- 变量声明的同时需要初始化
- 初始化表达式不能是方法组,也不是匿名函数
- 初始化表达式不是null
- 语句中只声明了一个变量
- 初始化表达式不能包含正在使用的变量
- 初始化
一种方法是使用无参的构造函数先实例化一个对象,然后分别为每个公开的属性赋值。另一种则是在构造函数中将属性值作为参数,在构造函数中为每个属性赋值,这里可以给公开和私有的赋值。使用自动实现属性,则可以使用对象初始化器,如下,三个类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 = }
};
匿名类型包含以下成员:
- 一个获取所有初始值的构造函数
- 公有的只读属性
- 属性的私有字段
- 重写了由object中继承的方法
关于投影初始化程序,简单地理解从一个集合中,抽取集合元素中的各别属性,组成一个匿名类型,从而返回一个包含匿名类型的集合,这也是为什么我们使用var关键字,因为我们真的不知道返回的类型,使用var让编译器替我们理解返回类型,那问题来了,这个匿名类型的声明是否由编译器帮我们生成?它帮我们生成了类型,使用反编译工具就能知晓。
请斧正。
15.C#回顾及匿名类型(八章8.1-8.5)的更多相关文章
-
C#:匿名类型
匿名类型和var关键字是Visual C# 3.0提供的一个新特性,var是隐式类型而并不是类型javascript中的var. var user = new { Id = 1, Name = &qu ...
-
C#3.0新特性:隐式类型、扩展方法、自动实现属性,对象/集合初始值设定、匿名类型、Lambda,Linq,表达式树、可选参数与命名参数
一.隐式类型var 从 Visual C# 3.0 开始,在方法范围中声明的变量可以具有隐式类型var.隐式类型可以替代任何类型,编译器自动推断类型. 1.var类型的局部变量必须赋予初始值,包括匿名 ...
-
c# 把一个匿名对象赋值给一个Object类型的变量后,怎么取这个变量? c# dynamic动态类型和匿名类 详解C# 匿名对象(匿名类型)、var、动态类型 dynamic 深入浅析C#中的var和dynamic
比如有一个匿名对象,var result =......Select( a=>new { id=a.id, name=a.name});然后Object obj = result ;我怎 ...
-
Entity Framework 6 Recipes 2nd Edition(11-5)译 ->; 从”模型定义”函数返回一个匿名类型
11-5. 从”模型定义”函数返回一个匿名类型 问题 想创建一个返回一个匿名类型的”模型定义”函数 解决方案 假设已有游客(Visitor) 预订(reservation)房间(hotel ) 的模型 ...
-
Javascript基础回顾 之(一) 类型
本来是要继续由浅入深表达式系列最后一篇的,但是最近团队突然就忙起来了,从来没有过的忙!不过喜欢表达式的朋友请放心,已经在写了:) 在工作当中发现大家对Javascript的一些基本原理普遍存在这里或者 ...
-
Linq专题之提高编码效率—— 第二篇 神一样的匿名类型
说起匿名类型,我们都知道这玩意都是为linq而生,而且匿名类型给我们带来的便利性大家在实战中应该都体会到了,特别适合于一次性使用,临时 使用这些场景,虽然说是匿名类型,也就是说是有类型的,只是匿名了而 ...
-
《精通C#》自定义类型转化-扩展方法-匿名类型-指针类型(11.3-11.6)
1.类型转化在C#中有很多,常用的是int类型转string等,这些都有微软给我们定义好的,我们需要的时候直接调用就是了,这是值类型中的转化,有时候我们还会需要类类型(包括结构struct)的转化,还 ...
-
当匿名类型遇上Distinct
首先定义一个简单类,并重写ToString方法. public class CommidityFilter { public string Property { get; set; } public ...
-
C#简单问题,不简单的原理:不能局部定义自定义类型(不含匿名类型)
今天在进行代码测试时发现,尝试在一个方法中定义一个委托,注意是定义一个委托,而不是声明一个委托变量,在编写的时候没有报错,VS也能智能提示,但在编译时却报语法不完整,缺少方括号,但实际查询并没有缺少, ...
随机推荐
-
JAVA 1.1
1. JASE : J2SE 这个就是我们现在在学的东西,他是一切Java的核心基础 JAME :J2ME : 他是Java的一个微型版,主要用来做移动开发 JAEE :J2EE Java企业版本,主 ...
-
100天后 - 100-days-later
赛斯·高汀(Seth Godin)的博客: http://sethgodin.typepad.com/seths_blog/2013/04/100-days-later.html 面对着数以千计的图 ...
-
基于Eclipse的Go语言可视化开发环境
http://jingyan.baidu.com/article/d7130635032e2f13fdf475b8.html 基于Eclipse的Go语言可视化开发环境 | 浏览:2924 | 更新: ...
-
Sublime Text 3关闭自动更新
Sublime Text 3关闭自动更新 第一步:help->enter license 这有两个: -– BEGIN LICENSE -– Michael Barnes Single User ...
-
ios Camera学习笔记
检测设备的摄像头是否可用: - (BOOL) isCameraAvailable{ return [UIImagePickerController isSourceTypeAvailable: UII ...
-
java获取真实的IP地址工具类
在实际项目中,有调用微信支付完成支付功能,在微信支付的请求参数中需要传递一个本机的ip地址,java代码运行环境目前为windows10以及centos7. 以下为获取ip地址工具类: package ...
-
#006 C语言大作业学生管理系统第三天
还差最后两部分 读取文件 恢复删除的学生信息 先学会处理文件的 知识点,再继续跟着视频做这个作业. 应该明天周六能把视频里手把手教的学生管理系统敲完 第二周尽量自己能完成C语言课本最后面那道学生管理系 ...
-
【PAT】B1033 旧键盘打字(20 分)
#include<stdio.h> #include<algorithm> #include<ctype.h> using namespace std; bool ...
-
【网络】高性能网络编程--下一个10年,是时候考虑C10M并发问题了
转载:http://www.52im.net/thread-568-1-1.html 1.前言 在本系列文章的上篇中我们回顾了过云的10年里,高性能网络编程领域著名的C10K问题及其成功的解决方案(上 ...
-
调查显示数据分析已取代Web开发成为第一用例
一项关于Python的开发者调查显示,编程语言现在主要用于数据分析,取代了之前的第一个用例Web开发. 去年秋天,由Python软件基金会和开发人员工具供应商JetBrains进行,2018 Pyth ...