15.C#回顾及匿名类型(八章8.1-8.5)
今天的篇幅应该会很长,除了回顾前面学的一些,还有写一些关于匿名类型的相关知识,总体上对后续的学习很有帮助,学好了,后面更容易理解,不明白的,那就前面多翻几次,看多了总是会理解的。那么,进入正题吧。
- 自动实现属性
我们的很多工作都是由编译器帮我们去完成,如我们要说的自动实现属性。使用自动实现属性时,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也能智能提示,但在编译时却报语法不完整,缺少方括号,但实际查询并没有缺少, ...
随机推荐
- 「ubuntu」通过无线网络安装Ubuntu Server,启动系统后如何连接无线网络
接触Ubuntu系统不久,发现无线网络环境下安装Ubuntu Server一个不太人性化的设计:在安装过程中选择无线网卡,即使用无线网络安装(此时需要选择Wi-Fi网络并输入密码),但系统安装完成重启 ...
- XNote Ver:0.79
隐藏主窗后,双击小图标显示主窗. 支持拖拉网页文字到小图标上,直接在当前项目上创建下级资料项目. 项目分类限50个汉字.
- 聚合数据全国天气预报api接口
查询天气预报在APP中常用的一个常用功能,聚合数据全国天气预报api接口可以根据根据城市名/id查询天气.根据IP查询天气.据GPS坐标查询天气.查询城市天气三小时预报,并且支持全国不同城市天气预报查 ...
- 多人操作sqlite3数据库冲突问题解决方法
问题描述:sqlite3数据放置在某一台电脑的某个共享文件夹下,操作数据库的应用程序安装在同一局域网下的很多台电脑上,由于存在多人同时使用该应用程序,所以存在多人同时操作数据库的情况.经过测试发现,最 ...
- EDM总结
1. 使用table 布局,align="center" 2. 尽量不要用padding-left ,padding-right 样式: 3. CSS的浮动定位: 4. 不 ...
- UVALive 6263 The Dragon and the knights --统计,直线分平面
题意:给n条直线,将一个平面分成很多个部分,再给m个骑士的坐标,在一个部分内只要有一个骑士即可保护该部分,问给出的m个骑士是不是保护了所有部分. 解法:计算每个骑士与每条直线的位置关系(上面还是下面) ...
- 2014 Super Training #2 C Robotruck --单调队列优化DP
原题: UVA 1169 http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show ...
- 性能测试一般过程与LR性能测试过程
性能测试作为测试分类的一个大类,等同于系统测试中的功能测试.安全性测试和配置测试等,因此她的测试过程是对整个测试类型中测试过程的一个描述,因此包含了测试需要的确认目标,熟悉系统.获得需求等部分,因此性 ...
- 日期选择器:jquery datepicker的使用
helloweba.com 作者:月光光 时间:2012-04-08 21:05 标签: jquery datepicker jquery ui 在jquery ui中,提供了一个非常实用 ...
- getEl mask 用法