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

相关推荐
qq_49244844623 分钟前
python测试selenium等待时间,并输出log,设置log级别
开发语言·python
吃辣椒的年糕3 小时前
C++ 课程学习笔记:从对象生命周期看资源管理之道
java·c语言·开发语言·c++
阿志iiii3 小时前
高效便捷Java代理技术:轻松实现Web集成
java·开发语言·代理模式
ZHHHHHJ663 小时前
PDFMathTranslate-翻译 ble core 5.4全文
开发语言·物联网
m0_748240913 小时前
Auto-go 环境配置
开发语言·后端·golang
Maybe_ch4 小时前
Blazor-<select>
开发语言·c#·blazor
华梦岚6 小时前
F#语言的学习路线
开发语言·后端·golang
lly2024066 小时前
XML 元素:结构化数据的基石
开发语言
钟离墨笺6 小时前
【c++】四种类型转换形式
开发语言·c++
一包烟电脑面前做一天7 小时前
C#、.Net 中级高级架构管理面试题杂烩
面试·架构·c#·.net·面试题