[你必须知道的.NET]第十一回:参数之惑---传递的艺术(上)

本文将介绍以下内容:

  • 按值传递与按引用传递深论
  • ref和out比较 
  • 参数应用浅析 

 

1. 引言

接上回《第九回:品味类型---值类型与引用类型(中)-规则无边》中,对值类型和引用类型的讨论,其中关于string类型的参数传递示例和解释,引起园友的关注和讨论,可谓一石激起千层浪。受教于装配脑袋的深切指正,对这一概念有了相当进一步的了解,事实证明是我错了,在此向朋友们致歉,同时非常感谢大家的参与,尤其是装配脑袋的不倦相告。

因此,本文就以更为清晰的角度,把我理解有误的雷区作做以深入的讨论与分析,希望通过我的一点点努力和探讨至少对如下几个问题能有清晰的概念:

  • 什么是按值传递?什么是按引用传递?
  • 按引用传递和按引用类型参数传递的区别?
  • ref与out在按引用传递中的比较与应用如何?
  • param修饰符在参数传递中的作用是什么?

2. 参数基础论

简单的来说,参数实现了不同方法间的数据传递,也就是信息交换。Thinking in Java的作者有过一句名言:一切皆为对象。在.NET语言中也是如此,一切数据都最终抽象于类中封装,因此参数一般用于方法间的数据传递。例如典型的Main入口函数就有一个string数组参数,args是函数命令行参数。通常参数按照调用方式可以分为:形参和实参。形参就是被调用方法的参数,而实参就是调用方法的参数。例如: 

using System;

public class Arguments
{
  
public static void Main(string [] args)
  {
    
string myString = "This is your argument.";
    
//myString是实际参数
    ShowString(myString);
  }

  
private void ShowString(string astr)
  {
    Console.WriteLine(astr);
  }
}


由上例可以得出以下几个关于参数的基本语法:

  1. 形参和实参必须类型、个数与顺序对应匹配;
  2. 参数可以为空;
  3. 解析Main(string [] args),Main函数的参数可以为空,也可以为string数组类,其作用是接受命令行参数,例如在命令行下运行程序时,args提供了输入命令行参数的入口。
  4. 另外,值得一提的是,虽然CLR支持参数默认值,但是C#中却不能设置参数默认值,这一点让我很郁闷,不知为何?不过可以通过重载来变相实现,具体如下:
static void JudgeKind(string name, string kind)
{
    Console.WriteLine(
"{0} is a {1}", name, kind);
}


static void JudgeKind(string name)
{
    
//伪代码
    if(name is person)
    {
        Console.WriteLine(name, 
"People");
    }
}

 这种方法可以扩展,可以实现更多个默认参数实现,不过,说实话有些多此一举,不够灵活,不爽不爽。 

3. 传递的基础

接下来,我们接上面的示例讨论,重点将参数传递的基础做以交代,以便对参数之惑有一个从简入繁的演化过程。我们以基本概念的形式来一一列出这些基本概念,先混个脸儿熟,关于形参、实参、参数默认值的概念就不多做交代,参数传递是本文的核心内容,将在后文以大量的笔墨来阐述。所以接下来的概念,我们就做以简单的引入不花大量的精力来讨论,主要包括: 

3.1 泛型类型参数

泛型类型参数,可以是静态的,例如MyGeneric<int>;也可以是动态的,此时它其实就是一个占位符,例如MyGeneric<T>中的T可以是任何类型的变量,在运行期动态替换为相应的类型参数。泛型类型参数一般也以T开头来命名。 

3.2 可变数目参数

一般来说参数个数都是固定的,定义为集群类型的参数可以实现可变数目参数的目的,但是.NET提供了更灵活的机制来实现可变数目参数,这就是使用param修饰符。可变数目参数的好处就是在某些情况下可以方便的提供对于参数个数不确定情况的实现,例如计算任意数字的加权和,连接任意字符串为一个字符串等。我们以一个简单的示例来展开对这个问题的论述,为:


在此基础上,我们将使用param关键字实现可变数目参数的规则和使用做以小结为:

  • param关键字的实质是:param是定制特性ParamArrayAttribute的缩写(关于定制特性的详细论述请参见第三回:历史纠葛:特性和属性),该特性用于指示编译器的执行过程大概可以简化为:编译器检查到方法调用时,首先调用不包含ParamArrayAttribute特性的方法,如果存在这种方法就施行调用,如果不存在才调用包含ParamArrayAttribute特性的方法,同时应用方法中的元素来填充一个数组,同时将该数组作为参数传入调用的方法体。总之就是param就是提示编译器实现对参数进行数组封装,将可变数目的控制由编译器来完成,我们可以很方便的从上述示例中得到启示。例如:

    static void ShowAgeSum(string team, params int[] ages){...}

实质上是这样子:

    static void ShowAgeSum(string team, [ParamArrayAttribute] int[] ages){...}

  • param修饰的参数必须为一维数组,事实上通常就是以群集方式来实现多个或者任意多个参数的控制的,所以数组是最简单的选择;
  • param修饰的参数数组,可是是任何类型。因此,如果需要接受任何类型的参数时,只要设置数组类型为object即可;
  • param必须在参数列表的最后一个,并且只能使用一次。  

4. 深入讨论,传递的艺术 

默认情况下,CRL中的方法都是按值传递的,但是在具体情况会根据传递的参数情况的不同而有不同的表现,我们在深入讨论传递艺术的要求下,就是将不同的传递情况和不同的表现情况做以小结,从中剥离出参数传递复杂表现之内的实质所在。从而为开篇的几个问题给出清晰的答案。

4.1 值类型参数的按值传递

首先,参数传递根据参数类型分为按值传递和按引用传递,默认情况下都是按值传递的。按值传递主要包括值类型参数的按值传递和引用类型参数的按值传递。值类型实例传递的是该值类型实例的一个拷贝,因此被调用方法操作的是属于自己本身的实例拷贝,因此不影响原来调用方法中的实例值。以例为证: 

// FileName    : Anytao.net.My_Must_net
// Description : The .NET what you should know of arguments. 
// Release      : 2007/07/01 1.0

// Copyright   : (C)2007 Anytao.com  http://www.anytao.com

using System;

namespace Anytao.net.My_Must_net
{
    
class Args
    {
        
public static void Main()
        {
            
int a = 10;
            Add(a);
            Console.WriteLine(a);
        }

        
private static void Add(int i)
        {
            i 
= i + 10;
            Console.WriteLine(i);
        }
    }
}


休息一下,请看下篇『第十二回:参数之惑---传递的艺术(下) 

 

参考文献

(USA)Jeffrey Richter, Applied Microsoft .NET Framework Programming

(USA)David Chappell, Understanding .NET

 

温故知新

[开篇有益]
[第一回:恩怨情仇:is和as]
[第二回:对抽象编程:接口和抽象类]
[第三回:历史纠葛:特性和属性]
[第四回:后来居上:class和struct]
[第五回:深入浅出关键字---把new说透]
[第六回:深入浅出关键字---base和this]
[第七回:品味类型---从通用类型系统开始]
[第八回:品味类型---值类型与引用类型(上)-内存有理]
[第九回:品味类型---值类型与引用类型(中)-规则无边]
[第十回:品味类型---值类型与引用类型(下)-应用征途]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/438746.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[你必须知道的.NET]第十二回:参数之惑---传递的艺术(下)

本文将介绍以下内容&#xff1a; 按值传递与按引用传递深论ref和out比较 参数应用浅析 接上篇继续&#xff0c;『第十一回&#xff1a;参数之惑---传递的艺术&#xff08;上&#xff09;』 4.2 引用类型参数的按值传递 当传递的参数为引用类型时&#xff0c;传递和操作的是指…

[你必须知道的.NET]第十三回:从Hello, world开始认识IL

本文将介绍以下内容&#xff1a; IL代码分析方法 Hello, world历史 .NET学习方法论1. 引言 1988年Brian W. Kernighan和Dennis M. Ritchie合著了软件史上的经典巨著《The C programming Language》&#xff0c;我推荐所有的程序人都有机会重温这本历史上的经典之作。从那时起…

[你必须知道的.NET]第十四回:认识IL代码---从开始到现在

本文将介绍以下内容&#xff1a; IL代码分析方法 IL命令解析 .NET学习方法论 1. 引言 自从『你必须知道.NET』系列开篇以来&#xff0c;受到大家很多的关注和支持&#xff0c;给予了anytao巨大的鼓励和动力。俱往昔&#xff0c;我发现很多的园友都把…

[你必须知道的.NET]第十五回:继承本质论

本文将介绍以下内容&#xff1a; 什么是继承&#xff1f;继承的实现本质1. 引言 关于继承&#xff0c;你是否驾熟就轻&#xff0c;关于继承&#xff0c;你是否了如指掌。 本文不讨论继承的基本概念&#xff0c;我们回归本质&#xff0c;从编译器运行的角度来揭示.NET继承中的…

海岸鸿蒙2018年标准物质,海岸鸿蒙——20年权威的标准物质研制单位

摘要&#xff1a;海岸鸿蒙创办于1996年&#xff0c;是专业从事国家标准物质研发、生产、销售的高新技术企业。海岸鸿蒙创办于1996年&#xff0c;是专业从事国家标准物质研发、生产、销售的高新技术企业。海岸鸿蒙自创办以来&#xff0c;一直秉持“以市场为导向&#xff0c;以科…

[你必须知道的.NET]第十六回:深入浅出关键字---using全接触

本文将介绍以下内容&#xff1a; using指令的多种用法using语句在Dispose模式中的应用1. 引言 在.NET大家庭中&#xff0c;有不少的关键字承担了多种角色&#xff0c;例如new关键字就身兼数职&#xff0c;除了能够创建对象&#xff0c;在继承体系中隐藏基类成员&#xff0c;还在…

华为双系统是鸿蒙系统吗,华为p50pro是鸿蒙系统吗-华为p50pro有双系统吗

华为p50pro的外观基本上就是延续了上一代的风格&#xff0c;没有什么太大的变化&#xff0c;不过影像能力还是非常令人期待的&#xff0c;下面一起来了解华为p50pro的系统方面&#xff0c;看看有没有你暂所不知的消息。近日&#xff0c;有消息曝光了华为 P50 Pro将会有 Harmony…

[你必须知道的.NET]第十七回:貌合神离:覆写和重载

本文将介绍以下内容&#xff1a; 什么是覆写&#xff0c;什么是重载覆写与重载的区别覆写与重载在多态特性中的应用1. 引言 覆写&#xff08;override&#xff09;与重载&#xff08;overload&#xff09;&#xff0c;是成就.NET面向对象多态特性的基本技术之一&#xff0c;两…

鸿蒙系统正式开源,余承东:鸿蒙系统正式开源,友商也可以使用!

鸿蒙OS2.0正式开源&#xff1a;从PPT走向前台&#xff0c;该谁脸红了&#xff1f;在9月10日的开发者大会上&#xff0c;华为鸿蒙2.0发布&#xff0c;已经不再是某些人嘴中的PPT、又哄又蒙的鸿蒙了。说鸿蒙是PPT的言论&#xff0c;在前不久还能看到&#xff0c;如今鸿蒙已经发布…

[你必须知道的.NET]第十八回:对象创建始末(上)

本文将介绍以下内容&#xff1a; 对象的创建过程内存分配分析内存布局研究1. 引言 了解.NET的内存管理机制&#xff0c;首先应该从内存分配开始&#xff0c;也就是对象的创建环节。对象的创建&#xff0c;是个复杂的过程&#xff0c;主要包括内存分配和初始化两个环节。例如&…

[你必须知道的.NET]第十九回:对象创建始末(下)

本文将介绍以下内容&#xff1a; 对象的创建过程内存分配分析内存布局研究接上回[第十八回&#xff1a;对象创建始末&#xff08;上&#xff09;]&#xff0c;继续对对象创建话题的讨论>>> 2.2 托管堆的内存分配机制 引用类型的实例分配于托管堆上&#xff0c;而线…

android material 颜色值,Android Material Colors 谷歌 Material Design 标准颜色

Android Material Colors谷歌 Material Design 标准颜色。调色板资源文件通过 doc-getter 自动抓取生成。运行 Demo 来查看效果。UsageGradlecompile com.takwolf.android.materialdesign:color:0.0.1Stylecolor/material_indigo_500color/material_indigo_700color/material_p…

突然吐字不清_要注意说话吐字不清小心是脑中风前兆

任何疾病发病之前往往会有一些前兆出现&#xff0c;像是脑中风这种疾病在发作之前也是有前兆的&#xff0c;若是朋友们能够尽早的发现就能够在发病前进行治疗了。朋友们要注意的是说话吐字不清小心是脑中风前兆&#xff0c;这是脑中风发病前的典型前兆&#xff0c;还有头晕、呕…

c++ vs release没有exe_未来安全 | 第一次Geant4培训总结 | 有没有你关注的问题呢?...

Geant4简介Geant4是蒙卡工具包&#xff0c;模拟很多粒子&#xff0c;记录一些统计量&#xff0c;用这些统计量去估计真实的物理实验的结果。蒙卡模拟程序&#xff0c;从最老的MCNP&#xff0c;到PENELOPE&#xff0c;FLUKA等。MCNP是用输入卡片(输入文件)实现的&#xff0c;在一…

[你必须知道的.NET]第二十一回:认识全面的null

说在&#xff0c;开篇之前 null、nullable、??运算符、null object模式&#xff0c;这些闪亮的概念在你眼前晃动&#xff0c;我们有理由相信“存在即合理”&#xff0c;事实上&#xff0c;null不光合理&#xff0c;而且重要。本文&#xff0c;从null的基本认知开始&#xff0…

html用表格做个人主页页面,利用HTML的表格进行页面布局

在DIVCSS布局出现前&#xff0c;基本上所用的网站都使用table来进行布局。因为table布局很简单&#xff0c;但是table布局不灵活且代码很多。下面将介绍怎样使用table来进行布局。实例&#xff1a;我们来布局一个常见网站后台程序的架构。布局图如下所示&#xff1a;实例代码&a…

cesium坡度坡向分析_景观设计分析图制作技巧到底是什么?

国外设计中&#xff0c;人们都开始用动态分析图啦厉害的不要不要啊&#xff01;如果你也想做如此高逼格的分析图记得往下看&#xff01;景观设计分析为&#xff1a;人文&#xff0c;背景&#xff0c;区位&#xff0c;现状&#xff0c;历史&#xff0c;功能&#xff0c;流线&…

采购模板html5,蓝色的采购信息管理系统手机界面wap模板

手机版大气信息管理系统界面模板&#xff0c;采购信息管理wap手机模板下载。资源下载此资源下载价格为4D币&#xff0c;请先登录资源文件列表codedown123-080801-25/business_log.html , 6657codedown123-080801-25/choose.html , 6869codedown123-080801-25/css/animate.css ,…

adobe audition cs6 能打开mpcm文件吗?_Adobe全家桶出现这些漏洞,赶紧上官网下载补丁吧...

导语&#xff1a;Adobe已发布了计划的2020年7月安全更新&#xff0c;涵盖了五个不同产品领域的缺陷&#xff1a;Creative Cloud Desktop&#xff1b;媒体编码器&#xff1b;下载管理器; 真正的服务&#xff1b;和ColdFusion。其中四个错误的严重性被评为严重&#xff0c;而其他…

详解CSS的相对定位和绝对定位

CSS的相对定位和绝对定位 一、Static 静态定位 通常情况下&#xff0c;我们元素的position属性的值默认为static 就是没有定位&#xff0c;元素出现在正常的文档流中&#xff0c;这个时候你给这个元素设置的left,right,bottom,top这些偏移属性都是没有效果的&#xff0c;不会生…