C# 7.2 对运算符使用“in parameter”
Posted
技术标签:
【中文标题】C# 7.2 对运算符使用“in parameter”【英文标题】:C# 7.2 use of "in parameter" for operators 【发布时间】:2019-03-18 01:31:27 【问题描述】:在 C# 7.2 中,我们看到为方法参数引入了 in
修饰符,以将只读引用传递给对象。我正在使用 7.2 开发一个新的 .NET Standard 项目,出于好奇,我尝试在结构的相等运算符的参数上使用 in
关键字进行编译。
即- public static bool operator == (in Point l, in Point r)
不是 - public static bool operator == (Point l, Point r)
一开始我对这行得通感到有些惊讶,但经过一番思考后,我意识到这两个版本的运算符之间可能没有功能差异。我想确认这些怀疑,但经过一番彻底的搜索后,我找不到任何明确谈论在运算符重载中使用 in
关键字的内容。
所以我的问题是这是否真的有功能差异,如果有,是否有任何特别的理由鼓励或不鼓励使用 in
和运算符参数。我最初的想法是没有区别,特别是如果操作符是内联的。但是,如果它确实有所作为,似乎 in 参数应该在任何地方使用(只读引用有意义的任何地方,即),因为它们提供了速度奖励,并且与ref
不同和out
,不需要用户在传递对象时预先添加这些关键字。这将允许更有效地传递值类型对象,而无需对方法和运算符的用户进行任何更改。
总的来说,这可能超出了大多数 C# 开发人员担心的那种小规模优化,但我很好奇它是否有效果。
【问题讨论】:
Point
是一个值类型,所以 in
在这里并没有什么区别。
这是因为操作符一般都是内联的吗?因为通常这会产生通过引用而不是值传递的区别。
@500-InternalServerError in
几乎只对值类型有用。是什么让您认为 in
与值类型一起使用时毫无意义。
@SeanM。您似乎高估了通过引用传递值的好处。除非值类型特别大,否则其他人正在对其进行变异而您实际上想观察这些变异,否则不会有太多收获。如果你的结构设计得很好,也就是说,它们没有明显大于引用的大小,那么通过引用将相当于复制值。对于设计不佳的值类型(或这些指南例外的极少数情况)来说,这确实是一种胜利。
我猜这些准则与常规方法完全相同:如果结构足够大,那么使用“in”是有意义的。 “足够大”是什么意思是另一个问题。
【参考方案1】:
这是否真的有功能上的区别...我最初的想法是没有区别,特别是如果操作符是内联的
由于运算符==
重载在MSIL
中像常规静态方法一样被调用,因此它具有功能差异。它可以帮助避免像常规方法那样不必要的复制。
有什么特别的理由鼓励或不鼓励使用 in 与运算符参数。
根据this article,建议在值类型大于System.IntPtr.Size
时应用in
修饰符。但重要的是值类型应为 readonly struct
。否则in
修饰符会损害性能,因为编译器会在调用结构体的方法和属性时创建一个防御性副本,因为它们可以改变参数的状态。
【讨论】:
以上是关于C# 7.2 对运算符使用“in parameter”的主要内容,如果未能解决你的问题,请参考以下文章
在哪个 .Net Framework 版本 C# 7.2 可用
无法在此 ref ClassName (byRef) 方法上使用类功能 C# 7.2
Visual Studio 2017 使用 C# 7.2 发布 ASP.NET Core 应用程序