开发者社区> 嗯哼9925> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

c#的default、using和yield使用小结

简介:
+关注继续查看

一、default的应用场合

1、switch...case
在switch语句中,如果没有任何case表达式与开关值匹配,则控制传递给跟在可选default标签后的语句。如果没有default标签,则控制传递到switch以外。
对于c#,为了便于维护,建议default项最好要写。
示例代码:

ContractedBlock.gifCode

2、在泛型类和泛型方法中,在预先未知以下情况时,如何将默认值分配给参数化类型T:
(1)T是引用类型还是值类型;
(2)如果T为值类型,则它是数值还是结构。
示例代码:

复制代码
    public class GenericClass<T>
    {
        
public static T GetDefaultT<T>(T obj)
        {
            obj 
= default(T); //将默认值分配给参数化类型T
            return obj;
        }
    }
复制代码

备注:  给定参数化类型T的一个变量obj,只有当T为数值类型而且不是结构时,语句t = 0才能正常使用;只有当T为引用类型时,语句obj= null才有效。
使用default关键字,对于数值类型会返回零,对于引用类型会返回空,对于结构,此关键字将返回初始化为零或空的每个结构成员,具体取决于这些结构是值类型还是引用类型。
看下面的代码:

ContractedBlock.gifCode

二、using的应用场合
1、直接引入命名空间
using System.Data.SqlClient; //引入命名空间
2.using别名。using + 别名 = 包括详细命名空间信息的具体的类型。
这种做法有个好处就是当同一个cs引用了两个不同的命名空间,但两个命名空间都包括了一个相同名字的类型的时候。当需要用到这个类型的时候,就每个地方都要用详细命名空间的办法来区分这些相同名字的类型。而用别名的方法会更简洁,用到哪个类就给哪个类做别名声明就可以了。
注意:并不是说两个名字重复,给其中一个用了别名,另外一个就不需要用别名了,如果两个都要使用,则两个都需要用using来定义别名的。
例如我们用以下语句引入using System.Data.SqlClient命名空间:
using SqlServer=using System.Data.SqlClient;
这时我们就可以用 SqlServer表示using System.Data.SqlClient命名空间,给程序书写带来方便。
3、using语句定义一个范围,在该范围内处理对象。
当年刚学asp.net那会,曾经对照着书本,吭哧吭哧动手写了很多类似下面的代码:

ContractedBlock.gifCode

直到遇到SqlHelper,才省了很多力气花在业务逻辑上,当年真是...,呵呵。
言归正传,什么时候适合用using呢?当在某个代码段中使用了类的实例,而希望无论因为什么原因,只要离开了这个代码段就自动调用这个类实例的Dispose方法。要达到这样的目的,用try...finally是可以的,但用using看起来更方便和简洁。看下面的代码:

ContractedBlock.gifCode

 我们看到,using确实比try...finally少几行代码,不过,它们的性能怎么样呢?看两个方法各自生成的对应的IL:
(1)使用using

(2)使用try...finally

原来它们的性能几乎是一样的。上面的两段IL可以作为using和try...finally性能的参照。如果你在程序中经常try...catch或者using,对性能的影响是很明显的。
需要引起注意的是,using实例化一个对象的时候,对应的类必须实现IDisposable接口,比如我们延续上面的代码,增加一个如下方法:

复制代码
        static void Test()
        {
            
using (Program program = new Program()) //编译器报错,Program类必须要实现IDisposable接口
            {
                
//do something
            }
        }
复制代码

正像注释写的那样,类Program必须实现IDisposable接口,写成class Program : IDisposable{...}这样就可以了。
三、yield的应用
1、迭代器块中用于向枚举数对象提供值或发出迭代结束信号。
它的形式如下:
yield return <expression>;或者yield break;
下面看一个示例: 

ContractedBlock.gifCode

2、几个要注意的地方 
(1)、计算表达式并以枚举数对象值的形式返回;expression 必须可以隐式转换为迭代器的 yield 类型。
(2)、yield 语句只能出现在iterator 块中,该块可用作方法、运算符或访问器的体。
这类方法、运算符或访问器的体受以下约束的控制:
a、不允许不安全块。
b、方法、运算符或访问器的参数不能是 ref 或 out。
c、yield 语句不能出现在匿名方法中。
(3)、当和expression一起使用时,yield return语句不能出现在catch块中或含有一个或多个catch子句的 try 块中。

3、最后,为了深入理解迭代,我们有必要介绍一下.net两个和迭代关联密切的接口:IEnumerable和IEnumerator
(1)、IEnumerable和IEnumerator元数据对比
a、IEnumerator

ContractedBlock.gifCode

b、IEnumerable

ContractedBlock.gifCode

(2)、说明
IEnumerator:提供在普通集合中遍历的接口,有Current,MoveNext(),Reset(),其中Current属性返回的是object类型,另外两个是实例方法;
IEnumerable: 暴露一个IEnumerator,支持在普通集合中的遍历;
IEnumerator<T>:继承自IEnumerator,有Current属性,返回的是T类型;
IEnumerable<T>:继承自IEnumerable,暴露一个IEnumerator<T>,支持在泛型集合中遍历。

(3)总结
a、通过分析(1)中的源码,你也可以从这两个接口的用词选择上,看出其不同:IEnumerable是一个声明式的接口,声明实现该接口的类是“可枚举(enumerable)”的,但并没有说明如何实现iterator;IEnumerator是一个实现式的接口,IEnumerator类就是一个iterator。
b、一个集合要支持foreach方式的遍历,必须实现IEnumerable接口(即必须以某种方式返回IEnumerator对象);
c、IEnumerator对象具体实现了iterator(通过内部的MoveNext(),Reset(),Current)。
d、IEnumerable和IEnumerator通过IEnumerable的GetEnumerator()方法建立了连接,客户端可以通过IEnumerable的GetEnumerator()得到IEnumerator对象,所以从实质上来讲,将GetEnumerator()看作IEnumerator对象的工厂方法也未尝不可。

 






本文转自JeffWong博客园博客,原文链接:http://www.cnblogs.com/jeffwongishandsome/archive/2009/06/20/1504377.html,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
SwiftUI极简教程31:Combine异步编程框架和MVVM开发模式的使用(下)
SwiftUI极简教程31:Combine异步编程框架和MVVM开发模式的使用(下)
169 0
ZSD/ZSA 随机分布参数的定义 | 带你读《大规模天线波束赋形技术原理与设计 》之二十七
小尺度信道建模主要考虑时间色散参数、频率色散 参数以及空间色散参数的建模。本节主要讨论对大规模天线传输性能有直接影 响的角度色散参数的建模。
3986 0
Django自带的auth登录认证
前言:我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统。此时我们需要实现包括用户注册、用户登录、用户认证、注销、修改密码等功能,这还真是个麻烦的事情呢。
1445 0
Django之路——11 Django用户认证组件 auth
用户认证  auth模块 1 from django.contrib import auth django.contrib.auth中提供了许多方法,这里主要介绍其中的三个: 1.1 、authenticate()    提供了用户认证,即验证用户名以及密码是否正确,一般需要username  password两个关键字参数 如果认证信息有效,会返回一个  User  对象。
1587 0
活动| 顶级专家、前沿课题,蚂蚁金服ATEC高校技术论坛即将启动!
小蚂蚁说: 6月6日,蚂蚁金服将于全国范围内启动ATEC高校技术论坛巡回演讲活动,届时将有蚂蚁金服顶级专家进行前沿课题分享,是个不可错过的产学交流盛宴! 前言 作为蚂蚁金服ATEC科技品牌之一,ATEC高校技术论坛将持续发布科技类话题、项目、活动等,以加深产学研之间的有效互动,为中国培养核心人才、掌握核心技术而共同努力。
2537 0
django 1.8 官方文档翻译: 3-1-4 视图装饰器
视图装饰器 Django为视图提供了数个装饰器,用以支持相关的HTTP服务。 允许的HTTP 方法 django.views.decorators.http 包里的装饰器可以基于请求的方法来限制对视图的访问。
846 0
Yomotsu 使用 THREE.js 创建的示例(Examples created by Yomotsu using THREE.js)
Yomotsu 使用 THREE.js 创建的示例(Examples created by Yomotsu using THREE.js) 太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循“署名-非商业用途-保持一致”创作公用协议 转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS、Android、Html5、Arduino、pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作。
1125 0
c# Default关键字
1、在switch语句中,如果没有任何 case 表达式与开关值匹配,则控制传递给跟在可选 default 标签后的语句。如果没有 default 标签,则控制传递到 switch 以外。       int id = int32.
585 0
【笔记】C#using的用法小结
C#关键字的用法不单只有一种方法的。现在我总结了一下Using和New的用法,顺便巩固下自己的知识。 Using (1)引用命名空间 using作为引入命名空间指令的用法规则为: using Namespace; 在.NET程序中,最常见的代码莫过于在程序文件的开头引入System命名空间,其原因在于System命名空间中封装了很多最基本最常用的操作,下面的代码对我们来说最为熟悉不过: using System; 这样,我们在程序中就可以直接使用命名空间中的类型,而不必指定详细的类型名称。
819 0
+关注
4715
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载