C#通过引用(ref关键字)问题
本文关键字:关键字 问题 ref 引用 | 更新日期: 2023-09-27 18:00:06
我很难理解C#中ref
关键字的确切作用。在我的C++代码中,我创建了一个字符串变量以及指向它的指针和引用变量。我将它传递给Delete或Change函数,不出所料,所有3个变量都在修改中。
但是,使用C#,我将创建变量x
,并使用字符串数据对其进行初始化。我正在创建一个变量y
,它应该是对x
的引用。然后,我使用ref
关键字将x
传递到Change
或Delete
方法中,从而修改方法中的变量以及x
。然而,y
没有被修改,即使它应该是对x
的引用,就像C++中一样。这也不仅仅是字符串的问题,因为我已经用C#对象尝试了上面的测试,并得到了相同的结果。
这是否意味着y
在我执行var y = x
时按值复制了x
?
C++
#include <iostream>
using namespace std;
void Delete(string &variable)
{
variable = "";
}
void Change(string &variable)
{
variable = "changed data";
}
void main()
{
string x = "data";
string *y = &x;
string &z = x;
Delete(x);
}
c#
namespace ConsoleApplication1
{
public class Program
{
public static void Main(string[] args)
{
var x = "data";
var y = x;
Change(ref x);
}
public static void Delete(ref string variable)
{
variable = null;
}
public static void Change(ref string variable)
{
variable = "changed";
}
}
}
此行:var y=x;使y成为x的副本,而不是c中x的引用#因此,当您调用Changed函数时,它不会发生更改。
似乎没有一种简单的方法可以在C#(或大多数其他语言)中重现相同的C++行为。
当您将非值类型的对象作为参数传递给函数时,对象是按值传递的,但对象内容(属性/字段等)是按引用传递的(您可以从函数内部更改它们),当您使用"ref"关键字传递对象时,对象本身是byref,也可以更改,(这与在c++/c中发送指针与向结构(其本身包含指针)发送双指针相同)。
除了"不安全"代码之外,没有其他方法可以在C#中重现这种行为。即使第二个变量的标识发生变化,C++也无法将指针固定到另一个变量,这在大多数其他语言中都是不可用的。
这不是字符串或任何其他类型的特殊功能。例如,在以下C++代码的末尾,"g"指向更新的"f",该"f"设置为"SomeOtherFoo":
Foo f;
Foo *g = &f;
f = SomeOtherFoo();
//'g' points to the updated 'f'
在"safe"C#中,在以下代码的末尾,"g"仍然是原始对象,而不是"SomeOtherFoo"返回的新对象:
Foo f = new Foo();
Foo g = f;
f = SomeOtherFoo();
//'g' does not point to the updated 'f'
问题的核心是字符串在C#中被视为值类型(基元),而在C++中被视为引用类型。因此,正如Haimovitz博士所写的那样,将一个字符串分配给另一个变量将简单地复制该值。
访问C#中变量的实际指针的一种方法是编写"不安全代码"。https://msdn.microsoft.com/en-us/library/aa288474(v=vs.71).aspx