【发布时间】:2010-10-06 11:58:16
【问题描述】:
我刚刚在使用 C# 时遇到此错误消息
属性或索引器不能作为 out 或 ref 参数传递
我知道是什么原因造成的,并快速解决了创建正确类型的局部变量,将其作为 out/ref 参数调用函数,然后将其分配回属性:
RefFn(ref obj.prop);
变成
{
var t = obj.prop;
RefFn(ref t);
obj.prop = t;
}
显然,如果属性不支持在当前上下文中获取和设置,这将失败。
为什么 C# 不为我做这些?
我能想到这可能会导致问题的唯一情况是:
- 线程
- 例外情况
对于线程,转换会影响写入发生的时间(在函数调用之后与函数调用中),但我宁愿怀疑任何依赖于它的代码在中断时都会得到很少的同情。
对于例外情况,需要关注的是;如果函数分配给几个ref 参数之一而不是抛出,会发生什么?任何微不足道的解决方案都会导致分配所有参数或不分配参数,什么时候应该分配,有些不应该分配。同样,我不认为这会被支持使用该语言。
注意:我了解生成此错误消息的机制。我正在寻找的是为什么 C# 不会自动实现琐碎的解决方法的基本原理。
【问题讨论】:
-
通向含糖编译器的道路是用善意铺就的。
-
它不能解决问题,因为它并不总是安全的。更根本的问题是
T类型的属性不应该只有getter 和setter 方法,还应该有ActUpon<U>([indexparams...,] ActionByRef<T,U> act, ref U param)方法。这样的方法将允许使用静态委托而不使用闭包 (ListOfPoints.ActUpon(4, (ref Point it, ref param) => {it.X += param;}, ref something);) 有效地执行像ListOfPoints[4].X += something这样的语句。 -
使用此答案底部的表达式解决此问题的可靠方法:stackoverflow.com/a/3059448/176877
标签: c# properties syntactic-sugar reference-parameters