Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我可以在C#函数(如C+)中使用引用吗+;? 在C++中,我可以做到这一点: int flag=0,int1=0,int2=1; int &iRef = (flag==0?int1:int2); iRef +=1;_C#_Reference - Fatal编程技术网

我可以在C#函数(如C+)中使用引用吗+;? 在C++中,我可以做到这一点: int flag=0,int1=0,int2=1; int &iRef = (flag==0?int1:int2); iRef +=1;

我可以在C#函数(如C+)中使用引用吗+;? 在C++中,我可以做到这一点: int flag=0,int1=0,int2=1; int &iRef = (flag==0?int1:int2); iRef +=1;,c#,reference,C#,Reference,其效果是int1递增 我必须修改一些旧的c代码,如果我能做类似的事情,那将非常有帮助,但我想。。。也许不是。有人吗?恐怕没有。您可以使用如下代码和指针: int flag=0,int1=0,int2=1; unsafe { int *iRef = (flag==0? &int1:&int2); *iRef +=1; } (不是说这是个好主意或什么:)如果您只需要修改函数中的值类型,那么就用ref关键字传递参数 i

其效果是int1递增


我必须修改一些旧的c代码,如果我能做类似的事情,那将非常有帮助,但我想。。。也许不是。有人吗?恐怕没有。您可以使用如下代码和指针:

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

(不是说这是个好主意或什么:)

如果您只需要修改函数中的值类型,那么就用
ref
关键字传递参数


int i=0

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

increment(ref i);

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

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


C#中没有直接等价物。有两种选择:

你可以用

另一种选择是使用保存该值的引用类型(类)。对于exmaple:

// 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;
//使用类似
公共类包装{
公共包装(T首字母){
该值=初始值;
}
公共T值{get;set;}
}
//你可以做:
布尔标志=假;
var int1=新包装(0);
var int2=新包装(1);
包装的iRef=标志?int2:int1;
iRef.Value=iRef.Value+1;

由于您使用的是类的引用,因此对
iRef
的赋值将复制引用,而上述操作将起作用。

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


在C#中不支持创建托管局部变量别名的功能。您可以使用形式参数来实现这一点—您可以创建任何变量的别名形式参数—但不能创建任何变量的别名局部参数

然而,没有技术上的困难阻止我们这样做;CLR类型系统支持“引用局部变量”。(它还支持ref返回类型,但不支持ref字段。)

几年前,我实际上编写了一个C#的原型版本,它支持ref局部变量和ref返回类型,并且工作得非常好,因此我们有经验证据证明我们可以成功地做到这一点。然而,这项功能很可能很快就会被添加到C#中,如果有的话。有关详细信息,请参阅

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

另请参见相关问题:

您可以使用类似的:

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

是的,你可以用C#7.0来实现。它支持返回引用和存储引用。查看我的答案。

我不想为了使用引用而将函数拆分为子函数。无论如何,谢谢。@Gio:我还没有看到一个恰当命名的函数不能提高可读性的例子。如果我必须在解码Mark的
Ref
类型(聪明的想法,
+1
来自我)和一个通过
Ref
获取参数的函数之间进行选择,我当然更喜欢一个函数。谢谢你的提示。我来看看。我见过命令行工具使用这个习惯用法,它要么从作为参数传递的文件中读取,要么从stdin:
std::istream&is=blah()中读取?ifs:std::cin
。我会使用
ifs
std::cin
调用函数,但其他人似乎不喜欢额外的函数调用。@sbi:但在C#中,流已经是引用类型,所以在C#中没有问题:流s=f?s1:s2;,别担心。只有当变量是值类型时,这才变得有趣,如Gio的示例中所示。在C#中,如果不使用形式参数,就无法为彼此生成两个值类型的局部变量别名。我理解这一点。我刚才是在回答你的陈述“编写两个变量共享同一存储空间的程序会导致代码难以阅读、理解、修改和维护。”情况并非总是如此。也请参见:
// 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;
int flag = 0, int1 = 0, int2 = 0;
Action increment = flag == 0 ? (Action) (() => ++int1) : () => ++int2;
increment();