c#支持按结果调用吗?
本文关键字:调用 结果 支持 | 更新日期: 2023-09-27 18:12:08
我知道c#中有3种参数求值类型:
- 默认值,按值
- ref,即by-ref
- out,它是通过引用的,但被认为是初始化的,并且强制分配
我的教授说c#也支持by-result,他解释为:
- 参数必须与lhs兼容
- 创建参数的本地副本并对其进行操作
- 方法体处理成功后,将副本的值写回参数源
简短的回答——不,它没有。
虽然不清楚teacher的意思,但有可能获得在文本上匹配的代码,例如
int i = 1; f(i); //now i is 2
使用捕获局部变量的lambda表达式。
int i = 1;
Action<int> f = v => i = 2 * v;
f(i);
Console.WriteLine(i); // now i is 2
注意i
在对f
的调用中是严格按值传递的。
f(42)
-参数对执行结果更改的变量没有任何影响。不,不是c#语言的显式特性。它不会出现主要的混叠问题,当一种语言只支持引用传递或将指针作为一阶语言特性时,混叠问题很常见。除了lock关键字之外,几乎没有语法使线程化更容易。
c#中的一个有用规则是禁止通过引用传递属性,这个问题只能通过call-by-result来解决。值得注意的是VB。NET没有这个规则,它通过自动实现按结果调用来解决这个问题。这确实有制造惊喜的诀窍。
它确实发生在另一个执行上下文中的MarshalByRefObject上。比如另一个AppDomain或另一台机器。因此,必须在调用之前跨上下文边界复制ref参数,然后再复制回来。然而,这在很大程度上对程序是透明的,不包括需要显式应用[Out]属性的怪癖。
我想你的教授可能指的是方法完成后的简单变量重新赋值(即i = DoSomething(i)
),或者可能是在后台导致变量重新赋值的运算符,即++
。
为了说明这一点:
class Immutable
{
public readonly int Value;
public Immutable(int value)
{
this.Value = value;
}
public static Immutable operator ++(Immutable obj)
{
return new Immutable(obj.Value + 1);
}
}
现在我们可以做以下操作:
Immutable a = new Immutable(1);
Immutable originalA = a;
Debug.Assert(a.Value == 1);
Debug.Assert(a == originalA); // Same instance (obviously).
a++;
Debug.Assert(a.Value == 2);
Debug.Assert(a != originalA); // New instance.
这似乎满足所有条件:
- 可以对
Immutable
类型的变量执行LHS赋值。 - operator方法接收到原始变量的副本(你可以在方法体中重新分配
obj
,它不会影响原始位置)。a
在操作符完成执行后被重新分配,并将指向新创建的实例。
编辑
虽然这绝对不是答案,因为它不满足任何点,我认为值得一提的是,你也可以通过传递指针来获得"by ref"语义,我相信每个人都知道。然而,有些人可能不知道的是,这也可以使用TypedReference
来完成,这是MS c#中的一个特殊野兽:
void DodgyIncrement()
{
int i = 0;
this.Increment(__makeref(i));
Debug.Assert(i == 1);
}
void Increment(TypedReference i)
{
__refvalue(i, int) += 1;
}