“.NET研究”谈谈C# 4.0新特性“缺省参数”的实现
C#4.0关于缺省参数的新特性,相信大家都不会陌生。所谓缺省参数,顾名思义,就是在声明方法的某个参数的时候为之指定一个默认值,在调用该方法的时候如果采用该默认值,你就无须指定该参数。和很多语言层面特性(语法糖)的实现一样,缺省参数也是编译器为我们玩的一个小花招。缺省参数最终体现为两个特殊的自定义特性OptionalAttribute和DefaultParameterValueAttribute 。
目录
一、缺省参数的用法
二、实现缺省参数的两个特性:OptionalAttribute和DefaultParameterValueAttribute
三、直接通过OptionalAttribute和DefaultParameterValueAttribute 定义缺省参数
一、缺省参数的用法
比如下面一个TestMethod方法,后面两个参数bar和baz就是缺省参数,默认值分别为“Bar”和“Baz”。
{
Console.WriteLine("{0, -5} - {1, -5} - {2, -5}", foo, bar, baz);
}
在调用TestMethod的时候,我们自由地选择采用缺省的参数值,或者覆盖该缺省值。
{
TestMethod("Foo");
TestMethod("Foo", "Bar1");
TestMethod("Foo", "Bar1", "Baz1");
}
下面是输出结果:
Foo - Bar1 - Baz
Foo - Bar1 - Baz1
缺省参数的使用有两个简单的限制,其一是:缺省参数的声明只能放在普通参数之后。如下代码中定义的TestMethod方法中,缺省参数bar后面跟一个非缺省参数baz,这样的代码是不能通过编译的(编译错误信息为:Optional parameters must appear after all required parameters)。
{
Console.WriteLine("{0, -5} - {1, -5} - {2, -5}", foo, bar, baz);
}
但是,缺省参数后面可以跟数组参数(params参数),实际上无论在什么情况下,params参数都只能是最后一个声明的参数。关于缺省参数的声明的位置限制,主要重载方法的识别机制决定的,这一点大家都很容易理解。
缺省参数的另一个限制是:指定的缺省值必须是一个常量,这就实际上为作为缺省参数的数据类型作了限制——只能是系统定义的基元类型。下面定义的TestMethod方法中,我们定义了一个DateTime类型的缺省参数,并将参数缺省值作为DateTime.Now。由于DateTime.Now不是常量,所以这样的代码也不能通过编译(编译错误消息:Default parameter value for 'date' must be a compile-time constant)。
{
//Others...
}
二、实现缺省参数的两个特性:OptionalAttribute和DefaultParameterValueAttribute
为什么缺省参数的默认值只能接受常量呢?如果你了解了缺省参数的本质,这就不是一个问题。那么缺省参数究竟是如何实现的呢?
和很多语言层面特性(语法糖)的实现一样,缺省参数也是编译器为我们玩的一个小花招,而真正编译后的东西都是我们再熟悉不过的玩意儿。当包含缺省参数的C#代码经过编译后,缺省参数体现在两个特殊的自定义特性OptionalAttribute和DefaultParameterValueAttribute 。前者将参数标识为缺省参数,后者指定其缺省值。
public sealed class OptionalAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class DefaultParameterValueAttribute : Attribute
{
public DefaultParameterValueAttribute(object value);
public object Value {get; }
}
对于最开始我们定义的TestMethod方法,编译后的形式如下所示。
[Optional, DefaultParameterValue("Bar")] string bar,
[Optional, DefaultParameterValue("Baz")] strin上海闵行企业网站设计与制作g baz)
{
//Others..
}
正是因为缺省参数的默认值最终是作为DefaultParameterValueAttribute的参数存在的,所以它必须是常量。
三、直接通过OptionalAttribute和DefaultParameterValueAttribute 定义缺省参数
既然缺省参数最终体现为OptionalAttribute和DefaultParameterValueAttribute 这两个特性,我们是否可以直接通过它们来定义缺省参数呢?答案是:当然可以,下面的代码一样可以正常执行。
{
TestMethod("Foo");
TestMethod("Foo","Bar1");
TestMethod("Foo","Bar1","Baz1");
}
private static void TestMethod(string foo,
[Optional, DefaultParameterValue("Bar")] string bar,
[Optional, DefaultParameterValue("Baz")] string baz)
{
//Others..
}
如果调用含有缺省参数的方法,并且没有显示指定该参数,编译器在编译的时候会自动将默认值附加上去。对于上面的Main方法,下面是与之等效的编译后代码。
{
TestMethod("Foo", "Bar", "Baz");
TestMethod("Foo", "Bar1", "Baz");
TestMethod("Foo", "Bar1", "Baz1");
}
虽然说我们通过OptionalAttribute和DefaultParameterValueAttribute 这两个特性也可上海企业网站设计与制作以定义缺省参数,但是当我们将缺省参数定义在普通参数之前是,编译器不会报错。倒是方法中缺省参数实际上就相当于普通参数了。
{
//TestMethod("Foo","Baz");
//上面的方法调用无效
TestMethod("Foo","Bar1","Baz1上海徐汇企业网站制作style='color:white;' href='http://www.93tj.com'>上海网站建设"color: #800000;">");
}
private static void TestMethod(string foo,
[Optional, DefaultParameterValue("Bar")] string bar,
string baz)
{
//Others..
}
“.NET研究”谈谈C# 4.0新特性“缺省参数”的实现相关推荐
- 精进不休 .NET 4.0 (4) - C# 4.0 新特性之命名参数和可选参数
[索引页] [源码下载] 精进不休 .NET 4.0 (4) - C# 4.0 新特性之命名参数和可选参数, 动态绑定(dynamic), 泛型协变和逆变, CountdownEvent, Barri ...
- mysql is双竖线_MySQL 5.0 新特性教程 存储过程:第二讲
MySQL 5.0 新特性教程 存储过程:第二讲推荐查看本文HTML版本 什么样的SQL语句在Mysql存储过程中才是合法的呢?你可以创建一个包含INSERT, UPDATE,DELETE, SELE ...
- GreenDao3.0新特性解析(配置、注解、加密)
Greendao3.0release与7月6日发布,其中最主要的三大改变就是:1.换包名 2.实体注解 3.加密支持的优化 本文里面会遇到一些代码示例,就摘了官方文档和demo里的例子了,因为他们的例 ...
- JDK5.0新特性系列---目录
JDK5.0新特性系列---目录 JDK5.0新特性系列---1.自动装箱和拆箱 JDK5.0新特性系列---2.新的for循环 JDK5.0新特性系列---3.枚举类型 JDK5.0新特性系列--- ...
- [转]C# 2.0新特性与C# 3.5新特性
C# 2.0新特性与C# 3.5新特性 一.C# 2.0 新特性: 1.泛型List<MyObject> obj_list=new List(); obj_list.Add(new MyO ...
- Servlet 3.0 新特性概述
Servlet 3.0 新特性概述 Servlet 3.0 作为 Java EE 6 规范体系中一员,随着 Java EE 6 规范一起发布.该版本在前一版本(Servlet 2.5)的基础上提供了若 ...
- Redis 6.0 新特性-多线程连环13问!
来自:码大叔 导读:支持多线程的Redis6.0版本于2020-05-02终于发布了,为什么Redis忽然要支持多线程?如何开启多线程?开启后性能提升效果如何?线程数量该如何设置?开启多线程后会不会有 ...
- WCF4.0新特性体验(3):标准终结点(Standard Endpoints)
今天在WCF4.0新特性体验第3节,我们介绍WCF4.0里的标准终结点概念,也就是Standard Endpoints. WCF4.0提供了那些标准终结点?他们有什么作用?如何使用标准终结点?如何该表 ...
- Servlet 2.0 Servlet 3.0 新特性
概念:透传. Callback 在异步线程中是如何使用的.?? Servlet 2.0 && Servlet 3.0 新特性 Servlet 2.0 && Servle ...
最新文章
- w7怎么查看电脑配置_学室内设计,对电脑配置有何要求?不懂戳这!
- 面试中经常出现的算法1(整理)
- 响应键盘delete键的删除功能
- C++Builder中ListView控件用法和示例总结整理
- SMS短信的C语言代码摘抄
- Filter过滤要登录的页面(重要)
- fcntl函数(网络编程会用)
- HTML DOM之节点操作方法(1)
- (SQuirreL SQL Client 客户端 )使用Apache Phoenix 实现 SQL 操作HBase
- 栈在表达式计算过程中的应用
- SuperSlide
- Linux系统初学者指南,观点|Linux 系统调用的初学者指南
- map排序;MD5加密
- mscomm32.ocx 注册 和 web 调用案例
- Forth 语言概要
- 制作maven模板框架
- Unity 跳转GooglePlay 谷歌商店 应用商店
- 处理 yarn 项目 has unmet peer dependency
- 可以旅游了_原水_新浪博客
- #业余学习 java基础
热门文章
- python自动化_python自动化测试-Behave框架的用法介绍 - python测试学习
- linux逻辑文件块,linux逻辑卷组创建以及修改
- java c 性能比较_java 中ArrayList与LinkedList性能比较
- 软件设计师考c语言,软件设计师教程考点精讲之C语言三大定律
- python二维数组换行输出_关于用python绘制二维数组的问题
- 一个小例子对多态简单的理解
- python包mdure_Python hashlib模块实例使用详解
- 如何查询linux服务器的网卡,Linux服务器如何查看有没有无线网卡
- h5页面禁止复制_H5移动端页面禁止复制技巧
- navicat for mysql 用户_Navicat for MySQL 怎么/怎么添加管理用户?Navicat for MySQL 添加管理用户教程_37游游网...