更改方法内的引用类型(字符串)

时间:2010-11-30 18:50:03

标签: c# oop

我将字符串变量传递给方法。我知道字符串是引用类型,但我在方法中分配的值丢失了。

public static void TestMethod(string myString)
{
    myString = "world";
}

static void Main(string[] args)
{
    string s = "hello";
    Console.WriteLine(s); // output is "hello"
    TestMethod(s);
    Console.WriteLine(s); // output is also "hello" not "world" !?
}

无论如何,例如,数组不会发生这种情况。有人可以解释为什么可能是原因吗?

4 个答案:

答案 0 :(得分:8)

因为myString = "world"为参数分配了一个新字符串,而不是更新现有字符串。要更新对字符串的原始引用,您必须使用ref传递参数。

public static void TestMethod(ref string myString)
{
    myString = "world";
}

static void Main(string[] args)
{
    string s = "hello";
    Console.WriteLine(s); // output is "hello"
    TestMethod(ref s);
    Console.WriteLine(s); // output is also "hello" not "world" !?
}

答案 1 :(得分:2)

是的,因为没有ref(或out),您无法为参数分配新对象。由于您没有通过ref传递它,因此方法外部的变量仍然引用未更改的原始字符串。因此,字符串是不可变的,因此在实例化后不创建新字符串就无法对其执行任何操作。

可以更改数组(或者可以更改数组的内容),因为数组中的引用不是不可变的(可以说my_object 1重新分配为“BLAH”)。您可以替换数组中的值并使其可以在数组外部访问,因为对方法之外的数组的引用没有更改。

Link to String in MSDN (talks about immutability)

答案 2 :(得分:1)

为此,您需要将“ref”关键字添加到方法签名中的参数中。

虽然你的字符串是通过引用传递的,但是当你将它传递给你的方法时,你有两个对同一个字符串的引用 - Main()中的一个和TestMethod()中的一个。当您在TestMethod()中为变量赋值时,您正在更改其引用,但不会更改Main()的变量引用的内容。

如果你能够从TestMethod()中更改字符串而不是重新分配,那么你会在Main()中看到效果,但是你不能使用字符串,因为它们是不可变的。

要进一步使用此功能,您可以尝试以下操作 - 更改TestMethod()以接收IList并将项目添加到此列表。您可以在从Main()传入的变量中看到这些新项。现在,如果您将TestMethod(IList listArg)更改为首先将listArg重新分配给新列表(即listArg = new List)然后添加项目,则Main()中的列表保持不变。这是同样的想法。

答案 3 :(得分:0)

字符串是不可变的,这意味着您不能像更改数组中的项一样更改它的值。您只能用不同的字符串对象替换字符串对象。

如果您尝试替换数组对象,也会发生同样的情况。这将在参数变量中放置一个新数组,但它不会更改用于调用方法的变量,因此不会替换传入的数组:

public static void TestMethod(string[] myArray) {
  myArray = new string[] { "world" };
}

除非您使用refout关键字,否则参数始终按值传递。对于引用类型,这意味着您传递了引用的副本。

使用ref关键字传递变量,以便您可以在方法中更改它:

public static void TestMethod(ref string myString) {
  myString = "world";
}