服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - 关于C# 4.0新特性“缺省参数”的实现详解

关于C# 4.0新特性“缺省参数”的实现详解

2022-09-14 15:41蒋金楠 C#

这篇文章主要给大家介绍了关于C# 4.0新特性“缺省参数”的实现,文中通过示例代码介绍的非常详细,对大家学习或者使用C# 4.0具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧

前言

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

目录

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

一、缺省参数的用法

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

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

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

?
1
2
3
4
5
6
1: static void Main(string[] args)
2: {
3:   TestMethod("Foo");
4:   TestMethod("Foo", "Bar1");
5:   TestMethod("Foo", "Bar1", "Baz1");
6: }

下面是输出结果:

   1: Foo   - Bar   - Baz
   2: Foo   - Bar1  - Baz
   3: Foo   - Bar1  - Baz1

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

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

但是,缺省参数后面可以跟数组参数(params参数),实际上无论在什么情况下,params参数都只能是最后一个声明的参数。关于缺省参数的声明的位置限制,主要重载方法的识别机制决定的,这一点大家都很容易理解。

缺省参数的另一个限制是:指定的缺省值必须是一个常量,这就实际上为作为缺省参数的数据类型作了限制——只能是系统定义的基元类型。下面定义的TestMethod方法中,我们定义了一个DateTime类型的缺省参数,并将参数缺省值作为DateTime.Now。由于DateTime.Now不是常量,所以这样的代码也不能通过编译(编译错误消息:Default parameter value for 'date' must be a compile-time constant)。

?
1
2
3
4
1: static void TestMethod(DateTime date = DateTime.Now)
2: {
3:  //Others...
4: }

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
1: [ComVisible(true), AttributeUsage(AttributeTargets.Parameter, Inherited=false)]
 2: public sealed class OptionalAttribute : Attribute
 3: {
 4: }
 5:
 6: [AttributeUsage(AttributeTargets.Parameter)]
 7: public sealed class DefaultParameterValueAttribute : Attribute
 8: {
 9:   public DefaultParameterValueAttribute(object value);
10:   public object Value {get; }
11: }

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

?
1
2
3
4
5
6
1: private static void TestMethod(string foo,
2:   [Optional, DefaultParameterValue("Bar")] string bar,
3:   [Optional, DefaultParameterValue("Baz")] string baz)
4: {
5:   //Others..
6: }

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
1: static void Main(string[] args)
 2: {
 3:   TestMethod("Foo");
 4:   TestMethod("Foo","Bar1");
 5:   TestMethod("Foo","Bar1","Baz1");
 6: }
 7:
 8: private static void TestMethod(string foo,
 9:   [Optional, DefaultParameterValue("Bar")] string bar,
10:   [Optional, DefaultParameterValue("Baz")] string baz)
11: {
12:   //Others..
13: }

如果调用含有缺省参数的方法,并且没有显示指定该参数,编译器在编译的时候会自动将默认值附加上去。对于上面的Main方法,下面是与之等效的编译后代码。

?
1
2
3
4
5
6
1: private static void Main(string[] args)
2: {
3:   TestMethod("Foo", "Bar", "Baz");
4:   TestMethod("Foo", "Bar1", "Baz");
5:   TestMethod("Foo", "Bar1", "Baz1");
6: }

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

?
1
2
3
4
5
6
7
8
9
10
11
12
1: static void Main(string[] args)
 2: {
 3:   //TestMethod("Foo","Baz");
 4:   //上面的方法调用无效
 5:   TestMethod("Foo","Bar1","Baz1");
 6: }
 7: private static void TestMethod(string foo,
 8:   [Optional, DefaultParameterValue("Bar")] string bar,
 9:   string baz)
10: {
11:   //Others..
12: }

总结

到此这篇关于C# 4.0新特性“缺省参数”的实现的文章就介绍到这了,更多相关C#4.0新特性“缺省参数”内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://www.cnblogs.com/artech/archive/2011/01/12/optionalparameter.html

延伸 · 阅读

精彩推荐
  • C#C#构建树形结构数据(全部构建,查找构建)

    C#构建树形结构数据(全部构建,查找构建)

    这篇文章主要介绍了C#构建树形结构数据(全部构建,查找构建),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    umeall4242022-01-24
  • C#C#图像识别 微信跳一跳机器人

    C#图像识别 微信跳一跳机器人

    这篇文章主要为大家详细介绍了C#图像识别,微信跳一跳机器人,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    宁静致远9182022-02-17
  • C#一个状态机的实现

    一个状态机的实现

    本文主要介绍了C#实现一个状态机的思路与方法,具有很好的参考价值,下面跟着小编一起来看下吧...

    诺贝尔8222021-12-22
  • C#C#拷贝整个文件夹及子目录和其中文件的方法

    C#拷贝整个文件夹及子目录和其中文件的方法

    这篇文章主要介绍了C#拷贝整个文件夹以及子目录和其中文件,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下...

    zhyue936272022-07-27
  • C#C#沉淀之委托的深入讲解

    C#沉淀之委托的深入讲解

    如果要给方法传递一个方法参数时,就可以使用委托。下面这篇文章主要给大家介绍了关于C#沉淀之委托的相关资料,文中通过示例代码介绍的非常详细,...

    东南有大树5162022-03-01
  • C#C#实现简单过滤非法字符实例

    C#实现简单过滤非法字符实例

    这篇文章主要介绍了C#实现简单过滤非法字符的方法,涉及C#针对字符串遍历与判断的相关技巧,非常简单实用,需要的朋友可以参考下...

    一只小青蛙9452021-11-04
  • C#c#中(,||)与(&,|)的区别详解

    c#中(,||)与(&,|)的区别详解

    这篇文章主要介绍了c#中(&&,||)与(&,|)的区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面...

    盛开的雨季9712022-08-15
  • C#C# SendMail发送邮件功能实现

    C# SendMail发送邮件功能实现

    这篇文章主要为大家详细介绍了C# SendMail发送邮件功能实现,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    shaomine5522022-01-12