首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >操作符重载时允许的C#7 'in‘参数

操作符重载时允许的C#7 'in‘参数
EN

Stack Overflow用户
提问于 2018-02-01 19:08:33
回答 1查看 762关注 0票数 7

最近对C# 7的添加非常棒,现在在最新的版本中,我们可以通过使用新的in关键字,更有效地将ValueType (struct)实例传递给引用函数(‘by’)。

在方法声明中使用inref意味着避免整个struct的额外“内存-blt”副本,这通常是为了保留按值语义所必需的。使用in,您可以获得这样的好处(传递指向源ValueType本身的指针),但与ref不同,被调用者不允许修改该目标(由编译器强制执行)。

除了提高设计意图的严谨性之外,in还有一个额外的好处,那就是调用站点语法比使用ref更轻松。实际上,您不需要在调用站点中提到in关键字;它是可选的。

无论如何,我注意到显然您可以使用C# 参数定义in-attributed操作符来重载

代码语言:javascript
复制
public static bool operator ==(in FILE_ID_INFO x, in FILE_ID_INFO y) => eq(in x, in y);
//       works:            -----^            -----^

如果by-ref语义在运行时行为中确实占上风的话,这是很好的。但是我会感到惊讶,因为尽管C#允许您在方法调用中省略in关键字,但是在调用站点 to 中生成的代码需要不同。也就是说,它需要发出(例如) OpCodes.Ldflda而不是OpCodes.Ldfld,等等。

还有一个事实是,操作符重载没有可以使用(尽管是可选的) in关键字来修饰的传统方法“调用站点”:

代码语言:javascript
复制
var fid1 = default(FILE_ID_INFO);
var fid2 = default(FILE_ID_INFO);

bool q =    fid1 ==    fid2;
//       ^--- in? ---^      

那么,有没有人知道编译器、JIT和运行时是否会遵守代码似乎允许表达的内容,从而调用带有in-parameters的操作符重载实际上将获得by-ref语义?我在医生里找不到任何关于这种情况的消息。由于上面显示的代码基本上继续工作,就像它没有in标记一样,我想替代方法是在这里忽略in关键字吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-01 19:22:46

简短的回答:编译器做正确的事情。相信编译器。

较长的答覆:

重载运算符只是静态方法的语法糖。对重载操作符的调用只是调用该方法的语法糖。

那是,

代码语言:javascript
复制
public static bool operator ==(S s1, S s2) { ... }

只是一种语法上的糖

代码语言:javascript
复制
public static bool op_Equality(S s1, S s2) { ... }

代码语言:javascript
复制
if (s1 == s2)

只是句法上的糖

代码语言:javascript
复制
if (S.op_Equality(s1, s2))

因此,对于普通静态方法和普通静态方法调用中的in注释,无论什么行为,都适用于作为运算符的静态方法,以及使用这些运算符的表达式的静态方法调用。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48570084

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档