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# 参考)

相关推荐
Java Fans9 分钟前
如何在Windows本机安装Python并确保与Python.NET兼容
开发语言·windows·python
The Future is mine22 分钟前
在.NET Core控制器中获取AJAX传递的Body参数
c#·.netcore
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ42 分钟前
saveOrUpdate 有个缺点,不会把值赋值为null,解决办法
java·开发语言
Eiceblue1 小时前
C# 快速检测 PDF 是否加密,并验证正确密码
开发语言·pdf·c#·visual studio
FL16238631291 小时前
C#报错 iText.Kernel.Exceptions.PdfException: ‘Unknown PdfException
开发语言·c#
En^_^Joy1 小时前
PyQt常用控件的使用:QFileDialog、QMessageBox、QTreeWidget、QRadioButton等
开发语言·python·pyqt
o独酌o3 小时前
鼠标的拖动效果
开发语言·javascript
张哈大3 小时前
【 java 集合知识 第二篇 】
java·开发语言·笔记·哈希算法
青临的踩坑之路4 小时前
Docker + Nginx + Logrotate 日志管理与轮换实践
java·开发语言
じ☆ve 清风°5 小时前
JavaScript 原型与原型链:深入理解 __proto__ 和 prototype 的由来与关系
开发语言·javascript·原型模式