C#4.0关于缺省参数的新特性,相信大家都不会陌生。所谓缺省参数,顾名思义,就是在声明方法的某个参数的时候为之指定一个默认值,在调用该方法的时候如果采用该默认值,你就无须指定该参数。和很多语言层面特性(语法糖)的实现一样,缺省参数也是编译器为我们玩的一个小花招。缺省参数最终体现为两个特殊的自定义特性OptionalAttribute和DefaultParameterValueAttribute 。

目录
一、缺省参数的用法
二、实现缺省参数的两个特性:OptionalAttribute和DefaultParameterValueAttribute
三、直接通过OptionalAttribute和DefaultParameterValueAttribute 定义缺省参数

  一、缺省参数的用法

  比如下面一个TestMethod方法,后面两个参数bar和baz就是缺省参数,默认值分别为“Bar”和“Baz”。

static void TestMethod(string foo, string bar = "Bar", string baz = "Baz")
{
Console.WriteLine("{0, -5} - {1, -5} - {2, -5}", foo, bar, baz);
}

  在调用TestMethod的时候,我们自由地选择采用缺省的参数值,或者覆盖该缺省值。

static void Main(string[] args)
{
TestMethod("Foo");
TestMethod("Foo", "Bar1");
TestMethod("Foo", "Bar1", "Baz1");
}

  下面是输出结果:

Foo - Bar - Baz
Foo - Bar1 - Baz
Foo - Bar1 - Baz1

  缺省参数的使用有两个简单的限制,其一是:缺省参数的声明只能放在普通参数之后。如下代码中定义的TestMethod方法中,缺省参数bar后面跟一个非缺省参数baz,这样的代码是不能通过编译的(编译错误信息为:Optional parameters must appear after all required parameters)。

上海徐汇企业网站设计与制作>

static void TestMethod(string foo, string bar = "Bar", string baz)
{
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)。

static void TestMethod(DateTime date = DateTime.Now)
{
//Others...
}

  二、实现缺省参数的两个特性:OptionalAttribute和DefaultParameterValueAttribute

  为什么缺省参数的默认值只能接受常量呢?如果你了解了缺省参数的本质,这就不是一个问题。那么缺省参数究竟是如何实现的呢?

  和很多语言层面特性(语法糖)的实现一样,缺省参数也是编译器为我们玩的一个小花招,而真正编译后的东西都是我们再熟悉不过的玩意儿。当包含缺省参数的C#代码经过编译后,缺省参数体现在两个特殊的自定义特性OptionalAttribute和DefaultParameterValueAttribute 。前者将参数标识为缺省参数,后者指定其缺省值。

[ComVisible(true), AttributeUsage(AttributeTargets.Parameter, Inherited=false)]
public sealed class OptionalAttribute : Attribute
{
}

[AttributeUsage(AttributeTargets.Parameter)]
public sealed class DefaultParameterValueAttribute : Attribute
{
public DefaultParameterValueAttribute(object value);
public object Value {get; }
}

  对于最开始我们定义的TestMethod方法,编译后的形式如下所示。

private static void TestMethod(string foo,
[Optional, DefaultParameterValue("Bar")] string bar,
[Optional, DefaultParameterValue("Baz")] strin上海闵行企业网站设计与制作g baz)
{
//Others..
}

  正是因为缺省参数的默认值最终是作为DefaultParameterValueAttribute的参数存在的,所以它必须是常量。

  三、直接通过OptionalAttribute和DefaultParameterValueAttribute 定义缺省参数

  既然缺省参数最终体现为OptionalAttribute和DefaultParameterValueAttribute 这两个特性,我们是否可以直接通过它们来定义缺省参数呢?答案是:当然可以,下面的代码一样可以正常执行。

static void Main(string[] args)
{
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方法,下面是与之等效的编译后代码。

private static void Main(string[] args)
{
TestMethod("Foo", "Bar", "Baz");
TestMethod("Foo", "Bar1", "Baz");
TestMethod("Foo", "Bar1", "Baz1");
}

  虽然说我们通过OptionalAttribute和DefaultParameterValueAttribute 这两个特性也可上海企业网站设计与制作以定义缺省参数,但是当我们将缺省参数定义在普通参数之前是,编译器不会报错。倒是方法中缺省参数实际上就相当于普通参数了。

static void Main(string[] args)
{
//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新特性“缺省参数”的实现相关推荐

  1. 精进不休 .NET 4.0 (4) - C# 4.0 新特性之命名参数和可选参数

    [索引页] [源码下载] 精进不休 .NET 4.0 (4) - C# 4.0 新特性之命名参数和可选参数, 动态绑定(dynamic), 泛型协变和逆变, CountdownEvent, Barri ...

  2. mysql is双竖线_MySQL 5.0 新特性教程 存储过程:第二讲

    MySQL 5.0 新特性教程 存储过程:第二讲推荐查看本文HTML版本 什么样的SQL语句在Mysql存储过程中才是合法的呢?你可以创建一个包含INSERT, UPDATE,DELETE, SELE ...

  3. GreenDao3.0新特性解析(配置、注解、加密)

    Greendao3.0release与7月6日发布,其中最主要的三大改变就是:1.换包名 2.实体注解 3.加密支持的优化 本文里面会遇到一些代码示例,就摘了官方文档和demo里的例子了,因为他们的例 ...

  4. JDK5.0新特性系列---目录

    JDK5.0新特性系列---目录 JDK5.0新特性系列---1.自动装箱和拆箱 JDK5.0新特性系列---2.新的for循环 JDK5.0新特性系列---3.枚举类型 JDK5.0新特性系列--- ...

  5. [转]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 ...

  6. Servlet 3.0 新特性概述

    Servlet 3.0 新特性概述 Servlet 3.0 作为 Java EE 6 规范体系中一员,随着 Java EE 6 规范一起发布.该版本在前一版本(Servlet 2.5)的基础上提供了若 ...

  7. Redis 6.0 新特性-多线程连环13问!

    来自:码大叔 导读:支持多线程的Redis6.0版本于2020-05-02终于发布了,为什么Redis忽然要支持多线程?如何开启多线程?开启后性能提升效果如何?线程数量该如何设置?开启多线程后会不会有 ...

  8. WCF4.0新特性体验(3):标准终结点(Standard Endpoints)

    今天在WCF4.0新特性体验第3节,我们介绍WCF4.0里的标准终结点概念,也就是Standard Endpoints. WCF4.0提供了那些标准终结点?他们有什么作用?如何使用标准终结点?如何该表 ...

  9. Servlet 2.0 Servlet 3.0 新特性

    概念:透传. Callback 在异步线程中是如何使用的.?? Servlet 2.0 && Servlet 3.0 新特性 Servlet 2.0 && Servle ...

最新文章

  1. w7怎么查看电脑配置_学室内设计,对电脑配置有何要求?不懂戳这!
  2. 面试中经常出现的算法1(整理)
  3. 响应键盘delete键的删除功能
  4. C++Builder中ListView控件用法和示例总结整理
  5. SMS短信的C语言代码摘抄
  6. Filter过滤要登录的页面(重要)
  7. fcntl函数(网络编程会用)
  8. HTML DOM之节点操作方法(1)
  9. (SQuirreL SQL Client 客户端 )使用Apache Phoenix 实现 SQL 操作HBase
  10. 栈在表达式计算过程中的应用
  11. SuperSlide
  12. Linux系统初学者指南,观点|Linux 系统调用的初学者指南
  13. map排序;MD5加密
  14. mscomm32.ocx 注册 和 web 调用案例
  15. Forth 语言概要
  16. 制作maven模板框架
  17. Unity 跳转GooglePlay 谷歌商店 应用商店
  18. 处理 yarn 项目 has unmet peer dependency
  19. 可以旅游了_原水_新浪博客
  20. #业余学习 java基础

热门文章

  1. python自动化_python自动化测试-Behave框架的用法介绍 - python测试学习
  2. linux逻辑文件块,linux逻辑卷组创建以及修改
  3. java c 性能比较_java 中ArrayList与LinkedList性能比较
  4. 软件设计师考c语言,软件设计师教程考点精讲之C语言三大定律
  5. python二维数组换行输出_关于用python绘制二维数组的问题
  6. 一个小例子对多态简单的理解
  7. python包mdure_Python hashlib模块实例使用详解
  8. 如何查询linux服务器的网卡,Linux服务器如何查看有没有无线网卡
  9. h5页面禁止复制_H5移动端页面禁止复制技巧
  10. navicat for mysql 用户_Navicat for MySQL 怎么/怎么添加管理用户?Navicat for MySQL 添加管理用户教程_37游游网...