总目录
前言
在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# 参考)