String是不可变的引用类型如何?证明了吗?
答案 0 :(得分:6)
您随时可以查看ECMA C# Language Specification:
8.2.1预定义类型
C#提供了一组预定义类型,其中大部分都是熟悉的 致C和C ++开发人员。该 预定义的引用类型是对象 和字符串。类型对象是 所有其他类型的终极基本类型。 类型字符串用于表示 Unicode字符串值。 类型的值 字符串是不可变的。
答案 1 :(得分:2)
证明该字符串(如果你的意思是System.String)当然是引用类型很容易。
所有值类型都应该继承自ValueType(隐式为caurse),但System.String直接从System.Object继承,因此使用消除方法字符串不能是其他任何引用类型。
Console.WriteLine("".GetType().BaseType); //prints System.Object
Console.WriteLine(1.GetType().BaseType); //prints System.ValueType
要检查不变性,您应该在System.String类中找到任何“mutating”方法。我找不到任何东西!因为所有“变异”方法实际上都返回另一个实例,你可以通过调用object.ReferenceEquals来轻松检查它:
Console.WriteLine(object.ReferenceEquals(s, s + "1")); //False
Console.WriteLine(object.ReferenceEquals(s, s.Insert(0, "12"))); //False
你也可以检查另一种方法,你会发现它们都具有相同的行为:它们返回新对象,但它们不会改变现有值。
来自class System.String文档:
不变性和StringBuilder 类强>
String对象称为immutable (只读),因为它的价值不能 在创建后进行修改。 似乎修改String的方法 对象实际上返回一个新的String 包含修改的对象。
答案 2 :(得分:1)
答案 3 :(得分:1)
证明只需要经历每个外部可访问的public
,protected
,internal
或protected internal
)成员并查看他们是否可以改变对象。他们都不能,因此它是不可改变的。
如何轻松:
参考类型强制成员定义的不变性:
public class TestClass
{
private readonly int _someValue;
public TestClass(int val){_someValue = val;}
public int Value{get{return _someValue;}}
}
仅由界面强制执行的不变性:
public class TestClass
{
private int _someValue;
public TestClass(int val){_someValue = val;}
public int Value{get{return _someValue;}}
}
这两个类都定义了不可变引用类型。第一个是内部和外部不可变的,第二个是内部可变的,但是外部不可变,因为没有外部可访问的方法可以改变任何实例成员的值。
String偶然是第二种情况,尽管这是一个实现细节。
答案 4 :(得分:0)
Why string is immutable and StringBuilder is mutable ?
字符串构建器是可变的。它是纯引用类型。以下示例'foo'作为引用类型传递。因此输出为helloanish: E.g:
class Program
{
static void Main(string[] args)
{
StringBuilder y =new StringBuilder();
y.Append("hello");
Program p = new Program();
p.foo( y);
Console.WriteLine(y );
}
void foo(StringBuilder sb)
{
sb .Append("anish:");
}
}
Stirng是不可变的。在某些方面它是值类型。这些被称为不可变。下面的例子'foo'传递的是一个字符串但是这个作为一个值类型。所以输出是'hello'< / p>
E.g:
class Program
{
static void Main(string[] args)
{
string y =string.Empty;
y="hello";
Program p = new Program();
p.foo( y);
Console.WriteLine(y );
}
void foo(string sb)
{
sb +="anish:";
}
}
注意:请注意字符串。还有一些其他类型。
不是为函数成员声明创建新的存储位置,而是可以在ref类型的帮助下使用相同的存储位置。
例如:
class Program
{
static void Main(string[] args)
{
string y ="";
y="hello";
Program p = new Program();
p.foo(ref y);
Console.WriteLine(y );
}
void foo(ref string sb)
{
sb="anish:";
}
}
输出不是你好,它是anish
输出类型:相同的参考。事情是,最初变量是未分配的。
查看我的博客:http:http://anishmarokey.blogspot.com/2009/08/mutable-vs-immutable.html
答案 5 :(得分:0)
String是C#中的引用类型。当我们创建类型字符串的变量时,会在内存中创建一个string类型的对象。创建后无法修改此对象。
如果我们为同一个字符串变量分配一些其他值,则在内存中创建新对象,并将字符串变量指向此对象的新地址。
这就是为什么字符串被视为不可变类型。
正如Ruel所说,您可以获得有关字符串类型here的更多信息。