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

相关推荐
lyw2056198 分钟前
微服务八股(自用)
java·开发语言
dot to one8 分钟前
Qt 中 QWidget涉及的常用核心属性介绍
开发语言·c++·qt
液态不合群16 分钟前
理解 C# 中的各类指针
java·开发语言·c#
可喜~可乐24 分钟前
C# SQLite高级功能示例
数据库·sql·sqlite·c#
橙子1991101625 分钟前
Kotlin 中的作用域函数
android·开发语言·kotlin
zimoyin25 分钟前
Kotlin 懒初始化值
android·开发语言·kotlin
chenglin01626 分钟前
‌C# 集成 FastDFS 完整指南‌
c#·fastdfs
chenyuhao202428 分钟前
链表的面试题4之合并有序链表
数据结构·链表·面试·c#
黄雪超1 小时前
JVM——方法内联之去虚化
java·开发语言·jvm
h汉堡1 小时前
C/C++内存管理
java·c语言·开发语言·c++·学习