我可以在像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();