C# 一门与时俱进的语言

C# 一门与时俱进的语言

类型系统

  • 类型系统:C#是一门静态类型语言;需要在代码中明确给出变量、参数以及返回值的类型等
  • C# 2 引入了可空值类型(nullable value type)。利用它可以有效表示未定的变量值,从而摆脱魔数(把-1用作集合的索引,或者用DateTime.MinValue表示日期等)的使用。
  • C# 7,使用者还可以采用readonly struct 这样的声明,将自定义结构体声明为不可变类型。此项特性原本旨在提升编译器生成代码的效率,但是也助于开发人员更准确的表达代码意图。
  • C# 8还计划加入可空引用类型(nullable refe
    rence type)。C# 8假设任何没有显示声明为可空的值都为非可空值,例如下面这个方法声明
    string Method(string x,string ? y)
    该方法参数与的类型很明确:x是非可空值,y则是可空值。方法的返回值(没有?符号)表示函数的返回值也是非可空的。
  • C# 3引入了匿名类型(anonymous type)和隐式局部变量(var),二者用于解决某些静态类型语言的缺陷:代码冗余。对于一个仅在单一方法中使用的数据形态,如果要为其专门创建额外的数据类型,不善于牛刀杀鸡。而使用匿名类型的好处在于,保持静态类型语言优势的同时,可以清晰简洁的描述数据形态。
 var book = new {Title=""Lost in the snow,Author = "Holly Webb"};
 string title = book.Title;
 string author = book.Author;

匿名类型主要用于LINQ查询语句,不过即便没有LINQ,为单一方法专门创建数据类型这种做法也不太可取。同样,如果调用了某类型的构造方法,就没有必要在同一条语句中显示声明该变量的类型了。下面两种声明方式哪一个更简洁一目了然:

Dictionary<string,string> map1 = new Dictionary<string,string>();//显示类型
var map2 = new Dictionary<string,string>();//隐式类型

隐式类型在处理匿名类型时不可或缺,在处理普通类型时,其重要性日益凸显。需要重点区分隐式类型动态类型这两个概念。注意以上代码中的变量map2,它属于静态类型,只是没有显示写出其类型而已。

  • 不过,匿名类型的作用域仅限于单个代码块,无法作用于方法的参数或者返回值。C# 7 引入元组的概念。元组是一种值类型变量,它可以有效的组织变量。元组的framework支持相对比较简单,单还需要额外的语言支持来实现对元素进行命名。可以使用元组来替代前文中的匿名类型:
	var book = { title = "Lost in the Snow",author = "Holly webb"};
	Console.WriteLine(book.title);
用元组替代匿名类型的用法只适用于部分场合,其好处之一是元组可以用作方法的参数和返回值。

代码更简洁

1.构造与初始化

首先考虑对象构造和初始化的方式。**委托(delegate)**应该是演化最多而且最快的一项特性。在C# 1 中,需要先写一个委托可以指向的方法,然后再写一大段代码来创建委托。例如,为一个按钮的Click事件订阅一个新的事件处理方法,在C# 1代码如下所示:

button.Click += new EventHandler(HandleButtonClick);

C# 2引入方法组转换匿名方法后,就可以采用以下方式来保存HandleButtonClick方法了:

button.Click += HandleButtonClick;//C#2

如果Click处理方法比较简单,也可以写一个匿名方法,不需要再单独创建方法:

button.Click += delegate{ MessageBox.Show("Clicked!"); };//C#3

另外,匿名函数的闭包(closure) 特性还有额外的好处:在匿名函数中访问其所在的上下文的局部变量。不过自从C# 3退出lambda表达式之后,匿名函数已渐渐失宠,因为lambda表达式几乎具备了匿名函数所有的特长,而且它的语法更简洁。

button.Click += (sender,args) => MessageBox.Show("Clicked"); //C#3
2.方法与属性声明
  • 自动实现的属性 是C#代码简洁中最显著的特性之一。例如C#1实现的以下代码:
private string name;
public string Name{
	get { return name ;}
	set { name = value; }
}

如果采用自动实现的属性,则仅需一行代码:

public string Name { get; set; }

此外,C# 6引入的表达式主题成员 进一步降低了C#语言的复杂度。假设有一个封装了string集合的类,该集合的Count和GetEnumerator()这两个成员,在C# 6以前需要写成如下形式:

public int Count { get { retrn list.Count;} }
public IEnumerator<string> GetEnumerator(){
	return list.GetEnumerator();
}

有了C# 6,就可以使用=>标记作为表达式主体成员,大幅简化代码:

public int Count => list.Count;
public IEnumerator<string> GetEnumertor()=>list.GetEnumerator();
  • C# 6 引入了内插字符串字面量 如以下代码:
throw new KeyNotFoundException($"No calendar system for ID {id} exists")
3.异步

C#5 采用async/await机制,进一步简化了主流语言的异步编程模式。此项特性共包含2项关于async方法的补充内容。

  • async方法会生成一个返回值,该返回值代表一个异步操作。这部分完全不需要开发人员介入。该返回值的类型一般是Task或者Task<T>。
  • async方法使用await表达式来消费异步操作。如果async方法使徒等待一个尚未完成的操作,该方法就会异步地暂停,直到操作完成后再继续进行。
    借上述特性,我们可以按照编写同步代码的方式来编写异步代码,同时让并发操作更接近自然的思维方式。参考如下示例代码,假设有一个由WindowsForms事件触发的异步方法:
private async Task UpdateStatus(){
	Task<Weather> weatherTask = GetWeatherAsync();  	//同时开始
	Task<EmailStatus> emailTask = GetEmailStatusAsync();//两个操作
	
	Weather weather = await weatherTask;		//异步地等待
	EmailStatus email = await emailTask;		//二者完成
	weatherLabel.Text = weather.Desc;			//更新用户界面
	inboxLabel.Text = email.InboxCount.ToString();
}

未完待续。。。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值