C# in 参数修饰符的使用

总目录


前言

在C#中,in 关键字 可用于以下上下文中:

  • 泛型接口和委托中的泛型类型参数
  • 作为参数修饰符,它允许按引用而不是按值向方法传递参数。
  • foreach 语句。
  • LINQ 查询表达式中的 from 子句。
  • LINQ 查询表达式中的 join 子句。

本文主要介绍 in 作为参数修饰符时如何使用。


一、in 参数修饰符

在 C# 7.2 及更高版本中,in 关键字可以用于修饰方法的参数,它表示该参数是一个只读引用。这意味着该参数在方法内部不能被修改,同时避免了复制大型结构体的开销,提高了性能。

csharp 复制代码
        static void Main(string[] args)
        {
            int num = 5;
            DisplayValue(in num);
        }


        static void DisplayValue(in int value)
        {
            // 以下代码会导致编译错误,因为不能修改 in 参数
            // value = 10; 
            Console.WriteLine($"The value is: {value}");
        }
  • in int value:这里的 in 修饰了 value 参数,表示 value 是一个只读引用。在 DisplayValue 方法内部,不能对 value 进行赋值操作,如 value = 10; 会导致编译错误。
  • DisplayValue(in num);:调用 DisplayValue 方法时,使用 in 关键字将 num 作为只读引用传递给方法。这样可以避免复制 num 的值,对于大型结构体来说,这可以提高性能,因为传递的是引用而不是副本。

二、使用场景

当您想要确保一个方法不能修改传递给它的参数时,您可以使用in关键字来修饰参数。这有助于提高代码的安全性和清晰度,特别是对于大对象或结构体,因为它们会以按值方式传递,但不会被方法内部改变。

csharp 复制代码
public void PrintValue(in int value)
{
    // value cannot be modified within this method
    Console.WriteLine(value);
}

请注意,当你使用in关键字时,你实际上是创建了一个不可变的引用副本,这意味着原始变量的内容不会受到影响,但是性能上可能会比直接传递更高效,因为它避免了复制整个结构体。

注意事项:

  • 使用in关键字传递参数时,编译器会阻止对参数进行任何可能改变其状态的操作。
  • 如果您尝试在一个不允许修改的地方修改in参数,编译器将会报错。
  • 对于非值类型(如类),由于它们总是通过引用传递,所以in关键字没有实际效果;它主要用于值类型(如结构体)。

三、实际应用案例

假设我们有一个表示二维点的结构体:

csharp 复制代码
public struct Point
{
    public int X { get; }
    public int Y { get; }

    public Point(int x, int y) => (X, Y) = (x, y);

    public void Deconstruct(out int x, out int y) => (x, y) = (X, Y);
}

我们可以编写一个方法,该方法接收一个Point实例作为in参数,确保该方法不会改变传入的Point实例:

csharp 复制代码
public void DisplayPoint(in Point point)
{
    // point is treated as read-only here
    (int x, int y) = point;
    Console.WriteLine($"Point: ({x}, {y})");
}

调用此方法时,即使point是可变的,一旦传递给DisplayPoint,它就只能被当作只读对待:

csharp 复制代码
Point p = new Point(10, 20);
DisplayPoint(in p); // p remains unchanged after the call

结语

回到目录页:C# 知识汇总

希望以上内容可以帮助到大家,如文中有不对之处,还请批评指正。


参考资料:
C# 中 in 参数和性能分析
in(C# 参考)

相关推荐
猷咪8 分钟前
C++基础
开发语言·c++
IT·小灰灰10 分钟前
30行PHP,利用硅基流动API,网页客服瞬间上线
开发语言·人工智能·aigc·php
快点好好学习吧11 分钟前
phpize 依赖 php-config 获取 PHP 信息的庖丁解牛
android·开发语言·php
秦老师Q12 分钟前
php入门教程(超详细,一篇就够了!!!)
开发语言·mysql·php·db
烟锁池塘柳012 分钟前
解决Google Scholar “We‘re sorry... but your computer or network may be sending automated queries.”的问题
开发语言
是誰萆微了承諾12 分钟前
php 对接deepseek
android·开发语言·php
2601_9498683616 分钟前
Flutter for OpenHarmony 电子合同签署App实战 - 已签合同实现
java·开发语言·flutter
星火开发设计30 分钟前
类型别名 typedef:让复杂类型更简洁
开发语言·c++·学习·算法·函数·知识
qq_1777673742 分钟前
React Native鸿蒙跨平台数据使用监控应用技术,通过setInterval每5秒更新一次数据使用情况和套餐使用情况,模拟了真实应用中的数据监控场景
开发语言·前端·javascript·react native·react.js·ecmascript·harmonyos
一匹电信狗44 分钟前
【LeetCode_21】合并两个有序链表
c语言·开发语言·数据结构·c++·算法·leetcode·stl