不是string
不可变吗?为什么以下示例中line
可以file.ReadLine()
一次又一次地重新分配?感谢。
int counter = 0;
string line;
// Read the file and display it line by line.
System.IO.StreamReader file =
new System.IO.StreamReader("c:\\test.txt");
while((line = file.ReadLine()) != null)
{
Console.WriteLine (line);
counter++;
}
file.Close();
// Suspend the screen.
Console.ReadLine();
答案 0 :(得分:15)
不是字符串不可变吗?
是的,字符串是不可变的。
为什么可以一次又一次地重新分配以下示例中的行
line
不是字符串。 line
是一个变量,它引用一个字符串。变量称为变量,因为它们不同。
这可能意味着这个事实是引用的属性。事实并非如此。
数字1是不可变的,对吗?无论你对1做什么,它都是1.如果你加10比1得到11,你没有改变 10或1. 10和1仍然是10和1.结果是11,一个全新的号码。
因此,如果数字是不可变的,那我为什么要说:
int x = 1;
x = x + 10;
?因为x
不是号码。 x
是变量,其中包含数字,变量可以变化。
让我们想一想另一个例子。想想在现实生活中不可改变的事物。比方说,硬币的价值。如果你有一毛钱,你可以做任何事情让它值得多于或少于10美分仍然有一角硬币。角色是不可变的。假设你有一个抽屉,你只保留一枚硬币,今天它包含一角硬币。明天你从抽屉里取出一角硬币并放入四分之一。如果一角硬币不变,你是怎么做到的? 变量就像抽屉。您可以更改其内容,即使抽屉中的对象是不可变的。
最后,你问题的标题清楚地表明了你混淆的根本原因:
为什么一次又一次地重新分配字符串对象?
对象不是首先可以分配的内容。 可以分配变量,变量不是对象。变量是存储位置,可以包含值。
如果你被某本书教过,变量是一种对象 - 并且许多初学者书籍犯了这个错误 - 那么扔掉那本书并获得一本体面的书没有谎言。 ReadLine
返回的字符串是对象。对该对象的引用是分配给变量。然后,该变量的值是对不可变对象的引用。
C#中有两件看起来像变量但语义略有不同的东西。
首先,const
本地或字段不是变量,因为常量不能改变。如果它们可以变化那么它们将是变量,而不是常量。如果你说
const string s = "Hello";
那么Hello
不仅是不可变的,而且s
也是如此。您应该只将const
用于逻辑上一直不可变的。黄金的价格,银行的名称,姓氏,这些都可以改变。黄金的原子量,pi的价值,这些东西永远不会改变,所以它们可以是const
。 C#只允许某些类型为const
,并且只允许某些表达式初始化const
。
readonly
字段位于const
和变量之间。 readonly字段是构造函数或字段初始值设定项中的变量,从任何其他位置写入都是非法的。 C#在构造函数或字段初始值设定项之外的所有代码中将只读字段视为值,而不是变量。
答案 1 :(得分:2)
不可变变量可以重新分配但不能变异。
在这个例子中:
string s1 = "hello";
string s2 = s1;
string s1 = "goodbye";
符号s1
被重新分配到新的字符串对象"再见" ,而s2
指的是同一个原始字符串(" hello"),因为该字符串从未变异。
答案 2 :(得分:2)
你的变量' line'应该被认为是指向字符串的指针,而不是字符串。
字符串本身无法更改。例如你不能做
long currentTime = System.currentTimeMillis();
long fireTime = 10 * 60 * 1000;
Intent ucintent = new Intent(getApplicationContext(),TimeAlarmReceiver.class);
ucintent.putExtra("isAlarm", true);
PendingIntent mTimeSlot = PendingIntent.getBroadcast(getApplicationContext(), (int) requestCode, ucintent, PendingIntent.FLAG_ONE_SHOT);
alarmManager.set(AlarmManager.RTC_WAKEUP,currentTime+ fireTime, mTimeSlot);
期望能够改变第五个字符。与你可以做的c对比
line[4] = 'a'
(无论如何大多数情况下)
答案 3 :(得分:1)
不可变并不意味着不能重新分配对象的引用,这意味着对象本身不能被改变(改变)。
您可以永久重新分配for,但无法自行更改任何字符串。
如果您将引用设为常量,则无法重新分配。