《C# in Depth:深入理解C#》读书笔记 - 隐式类型、对象初始化程序和匿名类型

本文介绍了C#3.0中引入的几项重要新特性,包括自动实现的属性、隐式类型的局部变量、对象及集合初始化程序、隐式类型的数组和匿名类型等。这些特性简化了代码编写,并提升了开发效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

理解隐式类型、对象初始化程序和匿名类型

在C# 3.0中,几乎每个新特性都是为LINQ服务的。所以,本文将介绍下面几个在C# 3.0中引入的新特性:

自动实现的属性
隐式类型的局部变量
对象和集合初始化程序
隐式类型的数组
匿名类型
其实这几个特性都是比较容易理解的,对于这几个特性,编译器帮我们做了更多的事情(想想匿名方法和迭代器块),从而简化我们的代码。

自动实现的属性

在C# 3.0以前,当我们定义属性的时候,一般使用下面的代码

复制代码
public class Book
{
private int _id;
private string _title;

public int Id
{
    get { return _id; }
    set { _id = value; }
}

public string Title
{
    get { return _title; }
    set { _title = value; }
}

}
复制代码
在C# 3.0中引入了自动实现的属性,编译器会帮我们做更多的转换,所以我们可以把上面的属性实现代码转换为:

public class Book
{
public int Id { get; set; }
public string Title { get; set; }
}
在使用了自动实现的属性之后,代码变短了,我们也没有必要再定义私有的字段。

其实,当查看过IL代码之后就会发现这里编译器帮我们定义了私有字段,实现了get/set方法。

注意,当使用结构的时候,如果要使用自动属性,会有一个小问题:所有的构造函数都需要显式地调用无参数的构造函数this(),只有这样,编译器才知道所有的字段都被明确的赋值了。

例如下面代码中,当我们删除”:this()”后,编译器就会报错。

复制代码
public struct Student
{
public int Id { get; set; }
public string Name { get; set; }
public string Gender { get; set; }

//在结构中使用自动属性一定要显式地调用无参数的构造函数this()
public Student(string name):this()
{
    this.Name = name;
}

}
复制代码
隐式类型的局部变量

C# 1.0和C# 2.0中的类型系统是静态、显示和安全的。

在C# 3.0中我们可以使用var关键字定义隐式类型的变量,但是变量仍然是静态类型,只是编译器可以帮助我们推断变量的类型。

下面看一段代码,使用隐式类型的语句跟注释掉的语句的IL代码是相同的:

复制代码
static void Main(string[] args)
{
var str = “hello world”;//string str = “hello world”;
var num = 9;// int num = 9;

Console.WriteLine(str.GetType());
Console.WriteLine(num.GetType());
Console.Read();

}
复制代码

通过代码的输出可以看到,每个隐式类型的变量都是静态类型(同样我们也可以通过VS单步调试来查看隐式类型变量的类型),在这里是编译器帮我们做了类型推断。

为了验证这一点,但我们给str变量赋一个整型的值时,就会得到一个”Cannot implicitly convert type ‘int’ to ‘string’”的错误。

static void Main(string[] args)
{
var str = “hello world”;//string str = “hello world”;
str = 9;
Console.Read();
}
隐式类型的限制

使用隐式类型的时候,会有一些限制,不是所有变量都能使用隐式类型:

被声明的变量是一个局部变量,不能是静态字段和实例字段
变量在声明时必须被初始化
编译器需要根据变量的值来推断变量的类型,否则就会出现编译时错误
初始化表达式不能为一个方法组,也不能为一个匿名函数(不进行强制类型转化)
var enter = delegate { Console.WriteLine(); };//编译错误
var enter = (Action)delegate { Console.WriteLine(); };//正常,因为编译器可以进行类型推断
初始化表达式不是null
因为null可以隐式转化为任何引用类型或可空类型,所以编译器不能进行类型推断
语句中只能声明一个变量
“var a = 2, b = 3;”会得到编译错误
隐式类型的优缺点

有些时候使用隐式类型可以减少代码长度,通过不影响代码可读性,反而使我们把注意力放在了更有用的代码上;但是,有时候隐式类型会是代码可读性变差。所以要自己衡量什么时候使用隐式类型的变量。下面看一个简单的例子

复制代码
static void Main(string[] args)
{
//简化了代码,没有牺牲可读性
var wordCount = new Dictionary

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值