C#语言入门详解(18)传值、输出、引用、数组、具名、可选参数、扩展方法

C#语言入门详解(18)传值、输出、引用、数组、具名、可选参数、扩展方法

  • 一、传值参数
    • 1. 值类型
    • 2. 引用类型,并且创建对象
    • 3. 引用类型,不创建对象
  • 二、引用参数
    • 1. 值类型
    • 2. 引用类型,创建新对象
    • 3. 引用类型,不创建新对象
  • 三、输出形参
    • 1. 值类型
    • 2. 引用类型
  • 四、数组参数
  • 五、具名参数
  • 六、可选参数
  • 七、扩展方法
  • 总结

内容来自刘铁猛C#语言入门详解课程。
参考文档:CSharp language specification 5.0 中文版在这里插入图片描述
在这里插入图片描述

一、传值参数

1. 值类型

  • 声明时不带修饰符的形参是值形参。 一个值形参对应于一个局部变量, 只是它的初始值来自该方法调用所提供的相应实参
    当形参是值形参时, 方法调用中的对应实参必须是表达式, 并且它的类型可以隐式转换为形参的类型。
    允许方法将新值赋给值参数。 这样的赋值只影响由该值形参表示的局部存储位置, 而不会影响在方法调用时由调用方给出的实参
    在这里插入图片描述
namespace ParametersExample
{class Program{static void Main{string[] args)Student stu = new Student()int y= 100;stu.AddOne(y);Console.WriteLine(y);
}class Student{public void AddOne(int x)x = x+ 1;Console.WriteLine(x):}

2. 引用类型,并且创建对象

在这里插入图片描述

  • 引用参数很少使用,一般情况都是传进来引用它的值,而不是连接到新对象去(基本只有面试题会考这个)。
  • 注:当参数类型为 string 时,在方法内部修改参数的值,对应的是此处创建对象这种情况。
    因为 string 是 immutable 的,所以在方法内部对 string 赋值实际是“创建新的 string 实例再赋值”,最终方法外部的 string 并不会改变。
  • Object.GetHashCode() 方法,用于获取当前对象的哈希代码,引每个对象的 Hash Code 都不一样,可通过 Hash Code 来区分两个 Name 相同的 stu 对象。
class Program
{static void Main(string[] args){var stu = new Student() { Name="Tim"};SomeMethod(stu);Console.WriteLine(stu.Name);Console.WriteLine(stu.GetHashCode());}static void SomeMethod(Student stu){//通过new修改指向地址stu = new Student { Name = "Tim" };Console.WriteLine(stu.Name);Console.WriteLine(stu.GetHashCode());}
}class Student
{public string Name { get; set; }
}

3. 引用类型,不创建对象

在这里插入图片描述

  • 这种通过传递进来的参数修改其引用对象的值的情况,在使用中比较少见。因为作为方法,其主要输出还是靠返回值。我们把这种修改参数所引用对象的值的操作叫做方法的副作用(side-effect),这种副作用平时编程时要尽量避免。
namespace ParametersExample
{class Program{static void Main(string[] args){Student stu = new Student() { Name = "Tim” };UpdateObject(stu);Console.WriteLine["HashCode={0}, Name-{1}", stu.GetHashCode(), stu.Name);}static void UpdateObject(Student stu){stu.Name="Tom";//副作用,side-effectConsole.WriteLine["HashCode-{0}, Name={1}", stu.GetHashCodel), stu.Name);}}
}

二、引用参数

1. 值类型

在这里插入图片描述

  • 引用形参是用 ref 修饰符声明的形参。 与值形参不同, 引用形参并不创建新的存储位置。相反,引用形参表示的存储位置恰是在方法调用中作为实参给出的那个变量所表示的存储位置。
  • 当形参为引用形参时,方法调用中的对应实参必须由关键字 ref 并后接一个与形参类型相同的 variablereference组成。 变量在可以作为引用形参传递之前, 必须先明确赋值。
  • 在方法内部, 引用形参始终被认为是明确赋值的。
static void Main(string[] args)
{int y = 1;IWantSideEffect(ref y);Console.WriteLine(y);
}static void IWantSideEffect(ref int x)
{x += 100;
}

2. 引用类型,创建新对象

在这里插入图片描述

class Program
{static void Main(string[] args){var outterStu = new Student() { Name = "Tim" };Console.WriteLine("HashCode={0}, Name={1}", outterStu.GetHashCode(), outterStu.Name);Console.WriteLine("-----------------");IWantSideEffect(ref outterStu);Console.WriteLine("HashCode={0}, Name={1}", outterStu.GetHashCode(), outterStu.Name);}static void IWantSideEffect(ref Student stu){stu = new Student() { Name = "Tom" };Console.WriteLine("HashCode={0}, Name={1}",stu.GetHashCode(),stu.Name);}
}class Student
{public string Name { get; set; }
}

在这里插入图片描述

3. 引用类型,不创建新对象

在这里插入图片描述

class Program
{static void Main(string[] args){var outterStu = new Student() { Name = "Tim" };Console.WriteLine("HashCode={0}, Name={1}", outterStu.GetHashCode(), outterStu.Name);Console.WriteLine("-----------------");SomeSideEffect(ref outterStu);Console.WriteLine("HashCode={0}, Name={1}", outterStu.GetHashCode(), outterStu.Name);}static void SomeSideEffect(ref Student stu){stu.Name = "Tom";Console.WriteLine("HashCode={0}, Name={1}", stu.GetHashCode(), stu.Name);}
}class Student
{public string Name { get; set; }
}

在这里插入图片描述

三、输出形参

  • 用 out 修饰符声明的形参是输出形参。类似于引用形参,输出形参不创建新的存储位置。相反,输出形参表示的存储位置恰是在该方法调用中作为实参给出的那个变量所表示的存储位置。
  • 当形参为输出形参时,方法调用中的相应实参必须由关键字 out 并后接一个与形参类型相同的 variablereference(第 5.3.3 节) 组成。变量在可以作为输出形参传递之前不一定需要明确赋值,但是在将变量作为输出形参传递的调用之后, 该变量被认为是明确赋值的。
  • 在方法内部,与局部变量相同,输出形参最初被认为是未赋值的,因而必须在使用它的值之前明确赋值。
  • 在方法返回之前,该方法的每个输出形参都必须明确赋值。声明为分部方法或迭代器的方法不能有输出形参。

1. 值类型

在这里插入图片描述

static void Main(string[] args)
{Console.WriteLine("Please input first number:");var arg1 = Console.ReadLine();double x = 0;if (double.TryParse(arg1, out x) == false){Console.WriteLine("Input error!");return;}Console.WriteLine("Please input second number:");var arg2 = Console.ReadLine();double y = 0;if (double.TryParse(arg2, out y) == false){Console.WriteLine("Input error!");return;}double z = x + y;Console.WriteLine(z);
}
  • 实现带有输出参数的TryParse:
class Program
{static void Main(string[] args){double x = 0;if(DoubleParser.TryParse("aa",out x)){Console.WriteLine(x);}}
}class DoubleParser
{public static bool TryParse(string input,out double result){try{result = double.Parse(input);return true;}catch{result = 0;return false;}}
}

2. 引用类型

在这里插入图片描述

  • 引用类型的输出参数实例
class Program
{static void Main(string[] args){Student stu = null;if(StudentFactory.Create("Tim", 34, out stu)){Console.WriteLine("Student {0}, age is {1}",stu.Name,stu.Age);}}
}class Student
{public int Age { get; set; }public string Name { get; set; }
}class StudentFactory
{public static bool Create(string stuName,int stuAge,out Student result){result = null;if (string.IsNullOrEmpty(stuName)){return false;}if (stuAge < 20 || stuAge > 80){return false;}result = new Student() { Name = stuName, Age = stuAge };return true;}
}

四、数组参数

在这里插入图片描述

  • params会自动声明一个数组,将给出值传入数组并传给函数。常用的writeLine / Split即为数组函数,先将参数传入object / char数组,再传给writeLine / Split函数。
  • 参数列表只允许有一个params参数,且必须放在最后的位置。
class Program
{static void Main(string[] args){var myIntArray = new int[] { 1, 2, 3 };int result = CalculateSum(myIntArray);Console.WriteLine(result);}static int CalculateSum(int[] intArray){int sum = 0;foreach (var item in intArray){sum += item;}return sum;}
}

等同于下面代码

class Program
{static void Main(string[] args){int result = CalculateSum(1, 2, 3);Console.WriteLine(result);}static int CalculateSum(params int[] intArray){int sum = 0;foreach (var item in intArray){sum += item;}return sum;}
}
  • WriteLine / Split示例
    在这里插入图片描述
    在这里插入图片描述

五、具名参数

在这里插入图片描述

  • 具名参数能提高代码的可读性
  • 不再受参数列表顺序的限制
class Program
{static void Main(string[] args){PrintInfo("Tim", 34);PrintInfo(age: 24, name:"Wonder");}static void PrintInfo(string name, int age){Console.WriteLine("Helllo {0}, you are {1}.",name,age);}
}

六、可选参数

在这里插入图片描述

  • 参数因为具有默认值而变得“可选”
  • 不推荐使用可选参数
class Program
{static void Main{string[] args){Printinfo();}
}static void Printinfo(string name = "Tim", int age = 34){Console.WriteLine("Hello {O}, you are {1}.", name, age);}

七、扩展方法

在这里插入图片描述
当无法对原始类进行修改时,可通过扩展方法为目标数据类型追加方法。扩展方法参数列表里第一个由this修饰,即为该参数数据类型的扩展方法。

  • 无扩展方法:
class Program
{static void Main(string[] args){double x = 3.14159;// double 类型本身没有 Round 方法,只能使用 Math.Round。double y = Math.Round(x, 4);Console.WriteLine(y);}
}
  • 有扩展方法:
class Program
{static void Main(string[] args){double x = 3.14159;// double 类型本身没有 Round 方法,只能使用 Math.Round。double y = x.Round(4);Console.WriteLine(y);}
}static class DoubleExtension
{public static double Round(this double input,int digits){return Math.Round(input, digits);}
}

在这里插入图片描述

  • LINQ实例
class Program
{static void Main(string[] args){var myList = new List<int>(){ 11, 12, 9, 14, 15 };//bool result = AllGreaterThanTen(myList);// 这里的 All 就是一个扩展方法bool result = myList.All(i => i > 10);Console.WriteLine(result);}static bool AllGreaterThanTen(List<int> intList){foreach (var item in intList){if (item <= 10){return false;}}return true;}
}

List所使用的All方法即为扩展方法,位于Linq命名空间下Enumrable静态类中。
在这里插入图片描述

总结

在这里插入图片描述

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

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

相关文章

模型部署:(二)安卓端部署Yolov5-v6.0目标检测项目全流程记录

模型部署&#xff1a;&#xff08;二&#xff09;安卓端部署Yolov5-v6.0目标检测项目全流程记录1、下载NCNN项目2、下载基于安卓的yolov5项目3、修改相应的配置文件4、将项目打包成apk包5、部署自己训练的yolov5模型6、相关资料下载&#xff1a;1、下载NCNN项目 # 链接地址 ht…

图形基础算法:如何将点与带曲线边的多边形位置关系算法做稳定

简介判断点与多边形位置关系算法是几何算法中最基础的算法之一&#xff0c;包括布尔运算在内的非常非常多的算法都会用到它。它的稳定是算法库稳定的关键。下面我们从一个边都是直线的多边形开始了解射线法的原理。然后看看引入曲线后会带来哪些问题&#xff0c;以及在实际应用…

react的filber架构

好问题 &#x1f44d; 你问的是 React Fiber 架构。这是 React 16 引入的核心机制&#xff0c;用来解决 React 在大规模更新时的性能问题。下面我给你从 背景 → Fiber 是什么 → 原理 → 优点 → 流程 来系统讲。一、为什么需要 Fiber&#xff1f;在 React 15 及以前&#xff…

Lucky STUN穿透结合群晖NAS实现docker下transmission监听端口动态更新

参考文章 LCUKY系列教程 一 「LUCKY STUN穿透」使用 cURL 自动修改 Transmission 的监听端口 二 「LUCKY STUN穿透」使用 Webhook 自动修改 qbittorrent 的监听端口 三 LUCKY STUN穿透在Windows上使用UPnP工具为BT客户端自动添加内外端口号不同的映射规则 四「LUCKY STUN穿透」…

如何在Ubuntu畅玩鸣潮等游戏

本教程只包括Steam上的游戏。# 更新软件源 sudo apt update # 安装Steam sudo apt install steam首先&#xff0c;在Ubuntu的snap商店安装Steam&#xff0c;启动&#xff0c;登陆&#xff0c;下载游戏。到这里的操作都比较简单&#xff0c;对于没有反作弊的游戏&#xff0c;往往…

机器学习09——聚类(聚类性能度量、K均值聚类、层次聚类)

上一章&#xff1a;机器学习08——集成学习 下一章&#xff1a;机器学习10——降维与度量学习 机器学习实战项目&#xff1a;【从 0 到 1 落地】机器学习实操项目目录&#xff1a;覆盖入门到进阶&#xff0c;大学生就业 / 竞赛必备 文章目录一、聚类任务&#xff08;无监督学习…

解决 Docker 构建中 Python 依赖冲突的完整指南

问题背景 在基于 registry.cn-shenzhen.aliyuncs.com/all_dev/dev:invoice-base 镜像构建 Docker 容器时,我们遇到了一个常见的 Python 依赖管理问题: ERROR: ResolutionImpossible: for help visit https://pip.pypa.io/en/latest/topics/dependency-resolution/#dealing-…

光子计算芯片实战:Lightmatter Passage互连架构性能评测

点击 “AladdinEdu&#xff0c;同学们用得起的【H卡】算力平台”&#xff0c;H卡级别算力&#xff0c;80G大显存&#xff0c;按量计费&#xff0c;灵活弹性&#xff0c;顶级配置&#xff0c;学生更享专属优惠。 摘要 随着人工智能计算需求呈指数级增长&#xff0c;传统电子计算…

基于树莓派与Jetson Nano集群的实验边缘设备上视觉语言模型(VLMs)的性能评估与实践探索

概述 2018年&#xff0c;TensorFlow Lite团队的Pete Warden曾提出&#xff1a;“机器学习的未来在于微型化”。如今&#xff0c;随着人工智能向高性能视觉强大的视觉语言模型&#xff08;Vision-language models, VLMs&#xff09;发展&#xff0c;对高性能计算资源的需求急剧…

华为Ai岗机考20250903完整真题

华为Ai岗机考20250903 华为自26届秋招&#xff08;2025年起&#xff09;对AI岗位机考进行了改革&#xff0c;考试题型调整为20道选择题&#xff08;15道单选(6分)5道不定项选择(12分)&#xff09;2道编程题(150300)。 题目核心围绕人工智能技术&#xff08;如Transformer架构…

k8s+jenkins+harbor构建Devops平台

一、环境准备1、准备一主一从k8s机器&#xff0c;&#xff08;设备好可以一主多从也行&#xff09;2、一台harbor仓库机器&#xff08;dockerhub访问不了&#xff09;二、安装nfs服务1、在k8s机器上yum install nfs-utils -y systemctl start nfs systemctl enable nfs2、创建共…

为什么 socket.io 客户端在浏览器能连上,但在 Node.js 中报错 transport close?

网罗开发&#xff08;小红书、快手、视频号同名&#xff09;大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等方…

人才教育导向下:老年生活照护实训室助力提升学生老年照护服务能力

一、老年生活照护实训室建设背景与意义 &#xff08;一&#xff09;适应老龄化社会需求 我国老龄化程度持续加深&#xff0c;老年照护服务人才缺口不断扩大。培养专业照护人才成为当务之急&#xff0c;职业教育需承担重要责任。点击获取实训室建设方案 &#xff08;二&…

我在嘉顺达蓝海的安全坚守

作为嘉顺达蓝海的资深安全员&#xff0c;每天清晨 6 点&#xff0c;我都会站在物流基地的入口处&#xff0c;看着一队队橙色的嘉顺达蓝海危险品运输车整齐列队。那抹醒目的橙色&#xff0c;不仅是嘉顺达蓝海的标志&#xff0c;更是我和 200 多名同事坚守 12 年的安全承诺。今天…

云原生监控系统 Prometheus大总结 20250909

本章内容如下&#xff1a; Prometheus 介绍 Prometheus 部署和配置 Node Exporter 采集数据 Pushgateway 采集数据 PromQL 查询语言 Grafana 图形化展示 Prometheus 标签管理 Prometheus 告警机制 Prometheus 服务发现 各种Exporter 高级功能 Prometheus 实现容器监控 Promethe…

EPNN:基于嵌入式偏振神经网络的水下成像增强方法(未做完)

Enhancing Underwater Imaging for Robot through Embedded Polarization Neural Network EPNN:基于嵌入式偏振神经网络的水下成像增强方法 1 论文核心概念 本文提出了一种名为嵌入式偏振神经网络(Embedded Polarization Neural Network, EPNN) 的方法,用于显著提升水下…

基于单片机冷藏运输车环境检测/水产品运输环境检测设计

传送门 &#x1f449;&#x1f449;&#x1f449;&#x1f449;单片机作品题目速选一览表&#x1f680; &#x1f449;&#x1f449;&#x1f449;&#x1f449;单片机作品题目功能速览&#x1f680; &#x1f525;更多文章戳&#x1f449;小新单片机-CSDN博客&#x1f68…

基于STM32设计的人体健康监护系统(华为云IOT)_280

文章目录 一、前言 1.1 项目介绍 【1】项目开发背景 【2】设计实现的功能 【3】项目硬件模块组成 【4】设计意义 【5】国内外研究现状 【6】摘要 1.2 设计思路 1.3 系统功能总结 1.4 开发工具的选择 【1】设备端开发 【2】上位机开发 1.5 参考文献 1.6 系统框架图 1.7 系统原理…

先买实现烦过

#include <myhead.h> #define ERR_LOG(msg)do{perror(msg);printf("%d %s %s\n",__LINE__,__func__,__FILE__);}while(0) //定义TFTP默认端口号&#xff08;69&#xff09;和数据包大小&#xff08;516字节&#xff09; #define PORT 69 #define N 516 …

ACD智能分配:轮流分配和排序上限分配的设置

在客户服务中&#xff0c;合理的对话分配是提高服务质量的关键。一洽客服系统针对不同业务场景,提供灵活的客服分配策略,帮助企业实现智能化的客户服务管理&#xff0c;今天我们了解一下对话的轮流分配、排序上限分配、排序优先分配的设置一、轮流分配按照客服登录系统的先后顺…