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

时间:2010-07-19 20:26:02

标签: c# reference

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

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

具有int1增加的效果。

我必须修改一些较旧的c#代码,如果我能做类似的事情会很有帮助,但我在想......也许不是。任何人

7 个答案:

答案 0 :(得分:8)

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


C#不支持您想要的功能 - 使托管本地变量别名。您可以使用形式参数来执行此操作 - 您可以创建一个形式参数,该参数是任何变量的别名 - 但您不能创建 local ,它是任何变量的别名。

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

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

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

另请参阅相关问题:Why doesn't C# support the return of references?

答案 1 :(得分:5)

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

如果您仍想这样做,请参阅Eric Lippert发布​​的Ref<T>课程here

sealed class Ref<T>
{
    private readonly Func<T> getter;
    private readonly Action<T> setter;
    public Ref(Func<T> getter, Action<T> 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<int> iRef = (flag == 0 ?
            new Ref<int>(() => int1, z => { int1 = z; }) :
            new Ref<int>(() => int2, z => { int2 = z; }));

         iRef.Value += 1;

        Console.WriteLine(int1);
    }
}

输出:

1

答案 2 :(得分:2)

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

int i = 0;

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

increment(ref i);

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

答案 3 :(得分:2)

是的,你可以用 C#7.0 来做到这一点。它支持返回引用和存储引用。请参阅我的回答here

答案 4 :(得分:1)

没有。您可以使用unsafe代码和指针来执行此操作:

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

(不是说这是一个好主意或任何事情:))

答案 5 :(得分:1)

C#中没有直接的平等。有几个选项 -

您可以使用unsafe code and pointers as suggested by dkackman

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

// Using something like
public class Wrapped<T> {
    public Wrapped(T initial) {
        this.Value = initial;
    }
    public T Value { get; set; }
}

// You can do:
bool flag=false;
var int1 = new Wrapped<int>(0);
var int2 = new Wrapped<int>(1);

Wrapped<int> iRef = flag ? int2 : int1;

iRef.Value = iRef.Value + 1;

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

答案 6 :(得分:1)

你可以像这样使用Action delegate

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