C#属性和ref参数,为什么不加糖?

标签 c# properties syntactic-sugar reference-parameters

我刚刚在使用 C# 时遇到了这个错误消息

A property or indexer may not be passed as an out or ref parameter

我知道是什么原因造成的,并快速解决了创建一个正确类型的局部变量,用它作为 out/ref 参数调用函数,然后将其分配回属性:

RefFn(ref obj.prop);

变成

{
    var t = obj.prop;
    RefFn(ref t);
    obj.prop = t;
}

很明显,如果属性在当前上下文中不支持 get 和 set,这将失败。

为什么 C# 不直接为我做这件事?


我能想到的唯一可能导致问题的情况是:

  • 线程
  • 异常(exception)情况

对于线程,转换会影响写入发生的时间(在函数调用之后与在函数调用中),但我宁愿怀疑任何依赖它的代码在中断时都不会得到同情。

对于异常(exception)情况,关注的是;如果函数分配给多个 ref 参数之一而不是抛出,会发生什么情况?任何微不足道的解决方案都会导致所有参数都被分配给某些参数,而某些参数不应该被分配。同样,我认为不支持使用该语言。


注意:我了解生成此错误消息的原因。我正在寻找的是 C# 不自动实现简单解决方法的基本原理。

最佳答案

因为您要传递索引器的结果,这实际上是方法调用的结果。无法保证 indexer 属性也有一个 setter,并且当开发人员认为他的属性将在没有调用 setter 的情况下被设置时,通过 ref 传递它会导致开发人员的错误安全。

在更技术层面上,ref 和 out 将传递给它们的对象的内存地址传递给它们,并且要设置一个属性,您必须调用 setter,因此不能保证该属性实际上会被更改,尤其是当属性类型是不可变的。 ref 和 out 不只是在方法返回时设置值,它们将实际的内存引用传递给对象本身。

关于C#属性和ref参数,为什么不加糖?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/529782/

相关文章:

c# - 为 Thread.Sleep(TimeSpan) 设置高值

python - 线程安全的 Python 属性/特性?

c# - 为什么递增运算符可以在属性上使用,而 ref 不行

java - 如何从代码完成中隐藏所有 java.lang.Object 方法?

c# - 计算算法时间

c# - C# 默认使用的 RSA 算法是什么,它在 Crypto++ 中的合适参数是什么?

scala - scala中是否有快速并发语法糖的实现?例如。 map 减少

c# - 如果在任何时候返回默认值,则停止 LINQ 查询

c# - 如何转换十进制?将 LINQ 与存储过程结合使用时转换为十进制

java - 获取属性文件 apache commons 中的条目数