我可以在像C ++这样的C#函数中使用引用吗?

在C ++中我可以这样做:

int flag=0,int1=0,int2=1; int &iRef = (flag==0?int1:int2); iRef +=1; 

具有int1增加的效果。

我必须修改一些旧的c#代码,如果我可以做类似的事情,那将会非常有用,但我在考虑……也许不是。 任何人?

可以做到 – 或者至少与你想要的东西非常相似 – 但最好找到另一种方法。 例如,您可以将整数包装在简单的引用类型中。

如果您仍想这样做,请参阅Eric Lippert发布​​的Ref类:

 sealed class Ref { private readonly Func getter; private readonly Action setter; public Ref(Func getter, Action setter) { this.getter = getter; this.setter = setter; } public T Value { get { return getter(); } set { setter(value); } } } public class Program { public static void Main() { int flag=0,int1=0,int2=1; Ref iRef = (flag == 0 ? new Ref(() => int1, z => { int1 = z; }) : new Ref(() => int2, z => { int2 = z; })); iRef.Value += 1; Console.WriteLine(int1); } } 

输出:

 1 

更新:下面讨论的function最终在C#7中添加。


C#不支持您想要的function – 创建托管本地变量别名 。 你可以使用forms参数来做 – 你可以创建一个forms参数,它是任何变量的别名 – 但你不能创建一个本地 ,它是任何变量的别名。

但是,阻止我们这样做没有技术上的困难; CLR类型系统支持“ref local variables”。 (它还支持ref返回类型,但不支持ref字段。)

几年前我实际上编写了一个C#的原型版本,它支持ref本地和ref返回类型,并且它工作得非常好,所以我们有经validation据表明我们可以成功地做到这一点。 但是,如果有的话,很快就会很快将此function添加到C#中。 有关详细信息,请参见http://ericlippert.com/2011/06/23/ref-returns-and-ref-locals/ 。

我注意到如果我是你,我会用任何语言避免这种情况。 编写两个变量共享相同存储的程序会使代码难以阅读,难以理解,难以修改且难以维护。

另请参阅相关问题: 为什么C#不支持引用的返回?

如果只需要修改函数中的值类型,则使用ref关键字传递参数。

int i = 0;

 void increment(ref int integer) { integer++; } increment(ref i); 

是的,你可以用C#7.0做到这一点。 它支持返回引用和存储引用。 在这里看到我的答案。

没有。 您可以使用不安全的代码和指针这样做:

  int flag=0,int1=0,int2=1; unsafe { int *iRef = (flag==0? &int1:&int2); *iRef +=1; } 

(不是说这是一个好主意或任何东西:))

C#没有直接的平等。 有几种选择 –

您可以使用dkackman建议的不安全代码和指针 。

另一种方法是使用保存值的​​引用类型(类)。 例如:

 // Using something like public class Wrapped { public Wrapped(T initial) { this.Value = initial; } public T Value { get; set; } } // You can do: bool flag=false; var int1 = new Wrapped(0); var int2 = new Wrapped(1); Wrapped iRef = flag ? int2 : int1; iRef.Value = iRef.Value + 1; 

由于您正在使用对类的引用,因此对iRef的赋值会复制引用,以上工作…

您可以像这样使用Action委托 :

 int flag = 0, int1 = 0, int2 = 0; Action increment = flag == 0 ? (Action) (() => ++int1) : () => ++int2; increment();