方法参数时可以使用的关键字:

  • params 指定此参数采用可变数量的参数。
  • in 指定此参数由引用传递,但只由调用方法读取。
  • ref 指定此参数由引用传递,可能由调用方法读取或写入。
  • out 指定此参数由引用传递,由调用方法写入。

Params:

使用 params 关键字可以指定采用数目可变的参数的方法参数。 参数类型必须是一维数组。
在方法声明中的 params 关键字之后不允许有任何其他参数,并且在方法声明中只允许有一个 params 关键字。
使用 params 参数调用方法时,可以传入:

  • 数组元素类型的参数的逗号分隔列表。
  • 指定类型的参数的数组。
  • 无参数。 如果未发送任何参数,则 params 列表的长度为零。
public class MyClass
{public static void UseParams(params int[] list){for (int i = 0; i < list.Length; i++){Console.Write(list[i] + " ");}Console.WriteLine();}public static void UseParams2(params object[] list){for (int i = 0; i < list.Length; i++){Console.Write(list[i] + " ");}Console.WriteLine();}static void Main(){// You can send a comma-separated list of arguments of the// specified type.UseParams(1, 2, 3, 4);UseParams2(1, 'a', "test");// A params parameter accepts zero or more arguments.// The following calling statement displays only a blank line.UseParams2();// An array argument can be passed, as long as the array// type matches the parameter type of the method being called.int[] myIntArray = { 5, 6, 7, 8, 9 };UseParams(myIntArray);object[] myObjArray = { 2, 'b', "test", "again" };UseParams2(myObjArray);// The following call causes a compiler error because the object// array cannot be converted into an integer array.//UseParams(myObjArray);// The following call does not cause an error, but the entire// integer array becomes the first element of the params array.UseParams2(myIntArray);}
}

In:

in 关键字会导致按引用传递参数,但确保未修改参数。
它让形参成为实参的别名,这必须是变量。
in 参数无法通过调用的方法进行修改。
in 形参的实参必须先经过初始化,然后才能传递。

in、ref 和 out 关键字不被视为用于重载决议的方法签名的一部分。什么意思呢?看下图

如果使用In关键字,就不能使用Ref和Out;
如果使用Ref关键字,就不能使用In和Out;
如果使用Out关键字,就不能使用In和Ref;
重载决策规则

  1. 定义使用 in 参数的方法是一项潜在的性能优化。 某些struct类型参数可能很大,在紧凑的循环或关键代码路径中调用方法时,复制这些结构的成本就很高。 方法声明in参数以指定参数可能按引用安全传递,因为所调用的方法不修改该参数的状态。 按引用传递这些参数可以避(可能产生的)高昂的复制成本。
  2. 指定 in 会声明你想按引用传递参数。在调用站点省略 in 就会通知编译器你将允许它创建临时变量,并按只读引用传递至方法。 编译器创建临时变量以克服一些 in 参数的限制:
    - 临时变量允许将编译时常数作为 in 参数。
    - 临时变量允许使用属性或 in 参数的其他表达式。
    - 存在从实参类型到形参类型的隐式转换时,临时变量允许使用实参。

Ref:

ref 关键字指示按引用传递值。 它用在四种不同的上下文中:

  • 在方法签名和方法调用中,按引用将参数传递给方法。
  • 在方法签名中,按引用将值返回给调用方。
  • 在成员正文中,指示引用返回值是否作为调用方欲修改的引用被存储在本地。 或指示局部变量按引用访问另一个值。
  • 在 struct 声明中,声明 ref struct 或 readonly ref struct。

使用 ref 关键字时,它指示参数按引用传递,而非按值传递。 ref 关键字让形参成为实参的别名,这必须是变量。 换而言之,对形参执行的任何操作都是对实参执行的。
传递到 ref 或 in 形参的实参必须先经过初始化,然后才能传递。

class Product
{public Product(string name, int newID){ItemName = name;ItemID = newID;}public string ItemName { get; set; }public int ItemID { get; set; }
}class Program
{private static void ChangeByReference(ref Product itemRef){// Change the address that is stored in the itemRef parameter.itemRef = new Product("Stapler", 99999);// You can change the value of one of the properties of// itemRef. The change happens to item in Main as well.itemRef.ItemID = 12345;}static void Main(string[] args){// Declare an instance of Product and display its initial values.Product item = new Product("Fasteners", 54321);System.Console.WriteLine("Original values in Main.  Name: {0}, ID: {1}\n",item.ItemName, item.ItemID);// Pass the product instance to ChangeByReference.ChangeByReference(ref item);System.Console.WriteLine("Back in Main.  Name: {0}, ID: {1}\n",item.ItemName, item.ItemID);}
}

引用返回值:
引用返回值(或 ref 返回值)是由方法按引用向调用方返回的值。 即是说,调用方可以修改方法所返回的值,此更改反映在调用方法中的对象的状态中。

  • 在方法签名中。
public ref decimal GetCurrentPrice()
  • 在 return 标记和方法的 return 语句中返回的变量之间。
return ref DecimalArray[0];

ref 局部变量:
ref 局部变量用于指代使用 return ref 返回的值。 无法将 ref 局部变量初始化为非 ref 返回值。 也就是说,初始化的右侧必须为引用。 任何对 ref 本地变量值的修改都将反映在对象的状态中,该对象的方法按引用返回值。

ref decimal estValue = ref Building.GetEstimatedValue();

ref 返回值和 ref 局部变量示例

public class Book
{public string Author;public string Title;
}public class BookCollection
{private Book[] books = { new Book { Title = "Call of the Wild, The", Author = "Jack London" },new Book { Title = "Tale of Two Cities, A", Author = "Charles Dickens" }};private Book nobook = null;public ref Book GetBookByTitle(string title){for (int ctr = 0; ctr < books.Length; ctr++){if (title == books[ctr].Title)return ref books[ctr];}return ref nobook;}public void ListBooks(){foreach (var book in books){Console.WriteLine($"{book.Title}, by {book.Author}");}Console.WriteLine();}
}class Program
{static void Main(string[] args){var bc = new BookCollection();bc.ListBooks();ref var book = ref bc.GetBookByTitle("Call of the Wild, The");if (book != null)book = new Book { Title = "Republic, The", Author = "Plato" };bc.ListBooks();}
}

Out:

out 关键字通过引用传递参数。 它让形参成为实参的别名,这必须是变量。 换而言之,对形参执行的任何操作都是对实参执行的。
若要使用 out 参数,方法定义和调用方法均必须显式使用 out 关键字。
out 参数传递的变量在方法调用中传递之前不必进行初始化。
被调用的方法需要在返回之前赋一个值。

class Program
{void OutArgExample(out int number){number = 44;}static void Main(string[] args){int initializeInMethod;OutArgExample(out initializeInMethod);Console.WriteLine(initializeInMethod);     // value is now 44}
}

In、Ref 和 Out 关键字不能用于以下几种方法:

  • 异步方法,通过使用 async 修饰符定义。
  • 迭代器方法,包括 yield return 或 yield break 语句。
  • 不能对扩展方法的第一个参数使用 out 关键字。
  • 扩展方法的第一个参数不能有 in 修饰符,除非该参数是结构。
  • 扩展方法的第一个参数,其中该参数是泛型类型(即使该类型被约束为结构。)

C#基础知识-方法参数Params、In、Ref、Out相关推荐

  1. C#学习笔记-方法参数params、ref和in、out

    目录 params 用法 ref 用法 按引用传递参数 引用返回值 引用局部变量 in 用法 特殊注意点 优势 out 用法 版本变迁信息 其他 ref.in和out三者异同 方法重载 C#中ref和 ...

  2. 计算机vb基础知识,2018年计算机二级考试VB基础知识:参数的传递

    2018年3月计算机等级考试即将开始,小编在这里为考生们整理了2018年计算机二级考试VB基础知识,希望能帮到大家,想了解更多资讯,请关注出国留学网的及时更新哦. 2018年计算机二级考试VB基础知识 ...

  3. JAVA基础知识——方法的参数,特殊数据类型,装箱和拆箱...

    文章目录 一.方法的参数 二.特殊的数据类型 三.装箱和拆箱 三.Object 四.思维导图 一.方法的参数 我们常见的参数有: (1)基本数据类型作为参数 (2)可变参数(三个点-) (3)引用类型 ...

  4. Linux操作系统基础知识命令参数详解

    Linux操作系统 RAID分组 RAID JBOD RAID JBOD的意思是Just a Bunch Of Disks,是将多块硬盘串联起来组成一个大的存储设备,从某种意义上说这种类型不被算作RA ...

  5. CMOS图像传感器基础知识和参数理解

    CMOS图像传感器的工作原理:每一个 CMOS 像素都包括感光二极管(Photodiode).浮动式扩散层(Floating diffusion layer).传输电极门 (Transfer gate ...

  6. C#中的Params、ref、out的区别

    C# Params params params 关键字可以指定在参数数目可变处采用参数的方法参数. 在方法声明中的 params 关键字之后不允许任何其他参数,并且在方法声明中只允许一个 params ...

  7. 【翻译】CodeMix入门基础知识

    CodeMix入门 CodeMix是一个Eclipse插件,可以直接从Eclipse访问VS Code和为Code OSS构建的附加扩展的各种技术.如果您是一位经验丰富的Eclipse开发人员,Cod ...

  8. codemix java,CodeMix入门基础知识

    CodeMix在线订购年终抄底促销!火爆开抢>> CodeMix入门 CodeMix是一个Eclipse插件,可以直接从Eclipse访问VS Code和为Code OSS构建的附加扩展的 ...

  9. 51单片机系列--基础知识

    51单片机系列--基础知识 主要参数及功能 引脚及功能 工作时序 主要参数及功能 (1)8位CPU (2)4KB程序存储器(ROM) (3)128字节的数据存储器(RAM) (4)32条 I/O 口线 ...

最新文章

  1. Linux下使用ssh动态验证码登陆机器
  2. 【Android 安全】DEX 加密 ( Proguard 混淆 | 混淆后的报错信息 | Proguard 混淆映射文件 mapping.txt )
  3. 迅捷路由连接服务器未响应,迅捷路由器通过falogin.cn登录不了管理界面的解决办法...
  4. leetcode 519. Random Flip Matrix | 519. 随机翻转矩阵(洗牌算法Fisher–Yates shuffle)
  5. CYQ.Data 数据框架 V4.0 开源版本发布(源码提供下载,秋色园V2.5版本标配框架)
  6. 我是如何把 Java 项目移植到 .NET 5.0 的
  7. qt实现QLabel上显示的文字有描边
  8. C/C++认识标准win32应用程序
  9. 【英语学习】【Daily English】U08 Dating L01 She is the one for me.
  10. 零基础转行Linux云计算运维工程师获得20万年薪的超级学习技巧
  11. 《世界是数字的 》的读后感
  12. c语言调用子程序实例,C语言程序调用汇编语言子程序
  13. JN5169 ZigBee 3.0 协议栈之 ZPS 配置编辑器
  14. 万维网联盟:已完成对HTML5的规范开发
  15. Comet OJ C1964 I am Groot
  16. 要做单片机课课设的快看过来1:KEIL安装以及C51环境搭建和Protues安装保姆教程
  17. 《红面书生》的算法博客
  18. 俄罗斯套娃信封问题 转https://www.jianshu.com/p/9d9495ef4372
  19. iPhoneX需求下滑对中国手机企业是好消息
  20. python2和python3的区别、转换及共存

热门文章

  1. 姐姐告诉我提眉的危害是什么,提眉术后多久可以恢复,纳尼,头大了
  2. 中国股市跳转大,但远低于高峰(上)
  3. MD5加密及第三方支付接口的技术比较
  4. 小米盒子2 攻破限制
  5. 魔兽版前端-大家好,我叫逗你玩!
  6. OLED如何播放badapple
  7. 各种神字体来袭,圈子球迷用书法作品为国足呐喊加油!
  8. Android音乐播放器(四)音乐唱片的转盘,歌曲同步进度条,以及音乐的暂停/播放/继续/上下歌曲切换
  9. Java学习之名称命名规范
  10. android版iphone6s,iPhone6s现在怎么样,相当于什么档次的安卓机?看完你就明白了...