我对参考类型感到非常困惑。我搜索了一下,发现字符串类型是引用类型。不是吗?
我的问题是:
我将一个字符串变量复制到另一个变量,并更改了第一个变量的值,但是第二个变量的值仍然相同。我不明白这个问题。即使字符串的类型是引用类型,第二个也不改变。我也尝试了装箱方法,但无法获得结果。
我读了这篇文章In C#, why is String a reference type that behaves like a value type?,但是我仍然感到困惑。
这是我的代码:
string my_text1 = "My text 1";
string my_text2 = my_text1;
my_text1 = "My text 2";
Console.WriteLine("First text --> " + my_text1); // It prints My text 2
Console.WriteLine("Second text -->" + my_text2); // It prints My text 1(I want it prints "My text 2" too)
string text_1 = "Example 1";
object text_2 = text_1;
text_1 = "Example 2";
Console.WriteLine("First example --> " + text_1); // It prints Example 2
Console.WriteLine("Second example -->" + text_2);// It prints Example 1
答案 0 :(得分:4)
分配是影响变量的动作。变量本身是独立的。值和引用类型之间的重要区别是 data 是存储在变量本身中还是存储在其他地方(并且变量仅包含引用)。
因此,在分配变量时,您可以更改该变量的内容 1 。就其本身而言,这不会对任何其他变量产生可见影响。
在变异数据时,您经常会注意到值类型和引用类型之间的区别。在这里,差异是很明显的,因为当您更改值类型的数据时,您是通过特定的变量来完成的,而您正在更改的是该变量的数据副本。而当您将数据更改为引用类型时,则对数据进行了更改,引用同一数据副本的所有变量对他们来说都是可见的更改。
但是,由于string
没有任何(没有反射技巧或不安全的代码)可变字段或变异方法,因此您永远无法使用string
变量来观察这种变异。
1 此处是指局部变量和字段。其他形式的赋值(例如分配给属性)可以运行任意代码,因此它们当然也可能具有其他明显的副作用。
答案 1 :(得分:3)
因为字符串是不可变的引用类型。
不可变类型是一种对象,其数据在创建后不能更改。不可变的字符串有很多好处。它提高了运行时效率和安全性(进程无法通过注入某些东西来更改字符串)。您可以read对其进行详细说明。
而且,字符串是引用类型的原因是,它们可能很大,需要存储在堆中。详细信息here
您可以使用可变的StringBuilder。
StringBuilder my_text1 = new StringBuilder("My text 1");
StringBuilder my_text2 = new StringBuilder("My text 2");
my_text1 = my_text2;
Console.WriteLine("First text --> " + my_text1);
Console.WriteLine("Second text -->" + my_text2);
在上面的示例中,两个表达式都将获得“我的文本2”。
答案 2 :(得分:0)
就像Damien_The_Unbeliever指出的那样,赋值总是会更改该变量,并且不会影响以前的变量。
将以下示例与类一起考虑
class Program
{
static void Main(string[] args)
{
Foo my_text1 = new Foo("My text 1");
Foo my_text2 = my_text1;
my_text1 = new Foo("My text 2");
Console.WriteLine("First text --> " + my_text1); // It prints My text 2
Console.WriteLine("Second text -->" + my_text2); // It prints My text 1
Foo text_1 = new Foo("Example 1");
object text_2 = text_1;
text_1 = new Foo("Example 2");
Console.WriteLine("First example --> " + text_1); // It prints Example 2
Console.WriteLine("Second example -->" + text_2);// It prints Example 1
}
}
class Foo
{
private readonly string _name;
public Foo(string name)
{
_name = name;
}
public override string ToString()
{
return _name;
}
}
字符串不能完全以这种方式工作,但是它使您了解Damien_The_Unbeliever的含义
如果您希望变量充当参考,则应添加ref关键字
string my_text1 = "My text 1";
ref string my_text2 = ref my_text1;
my_text1 = "My text 2";
Console.WriteLine("First text --> " + my_text1); // It prints My text 2
Console.WriteLine("Second text -->" + my_text2); // It prints My text 2