最近对C# 7的添加非常棒,现在在最新的版本中,我们可以通过使用新的in关键字,更有效地将ValueType (struct)实例传递给引用函数(‘by’)。
在方法声明中使用in或ref意味着避免整个struct的额外“内存-blt”副本,这通常是为了保留按值语义所必需的。使用in,您可以获得这样的好处(传递指向源ValueType本身的指针),但与ref不同,被调用者不允许修改该目标(由编译器强制执行)。
除了提高设计意图的严谨性之外,in还有一个额外的好处,那就是调用站点语法比使用ref更轻松。实际上,您不需要在调用站点中提到in关键字;它是可选的。
无论如何,我注意到显然您可以使用C# 参数定义in-attributed操作符来重载。
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关键字来修饰的传统方法“调用站点”:
var fid1 = default(FILE_ID_INFO);
var fid2 = default(FILE_ID_INFO);
bool q = fid1 == fid2;
// ^--- in? ---^ 那么,有没有人知道编译器、JIT和运行时是否会遵守代码似乎允许表达的内容,从而调用带有in-parameters的操作符重载实际上将获得by-ref语义?我在医生里找不到任何关于这种情况的消息。由于上面显示的代码基本上继续工作,就像它没有in标记一样,我想替代方法是在这里忽略in关键字吗?
发布于 2018-02-01 19:22:46
简短的回答:编译器做正确的事情。相信编译器。
较长的答覆:
重载运算符只是静态方法的语法糖。对重载操作符的调用只是调用该方法的语法糖。
那是,
public static bool operator ==(S s1, S s2) { ... }只是一种语法上的糖
public static bool op_Equality(S s1, S s2) { ... }和
if (s1 == s2)只是句法上的糖
if (S.op_Equality(s1, s2))因此,对于普通静态方法和普通静态方法调用中的in注释,无论什么行为,都适用于作为运算符的静态方法,以及使用这些运算符的表达式的静态方法调用。
https://stackoverflow.com/questions/48570084
复制相似问题