C# 值类型和引用类型(番外篇)

预定义的引用类型.

c#支持两种预定义的引用类型:object 和 string

  • object 根类型,其他类型都是从它派生而来的(包括值类型)
  • string Unicode字符串

object 类型

许多编程语言和类层次结构都提供了根类型, 层次结构中的其他对象都从它派生而来。c#和 .net 也不例外。

在c#中, object 类型就是最终的父类型, 所有内置类型和用户定义的类型都从它派生而来。

这样 object 类型就可以用于两个目的:

  • 可以使用 object 引用来绑定任何特定子类型的对象。 object引用也可以用于反射,此时必须有代码来处理类型未知的对象。
  • object 类型实现了许多一般用途的基本方法, 包括 Equals() 、GetHashCode()、GetType() 和 ToString()。 用户定义的类需要使用一种面向对象技术,来提供其中一些方法的替代实现代码。 例如,重写ToString()时, 要给类提供一个方法,给出类本身的字符串表示。如果类中没有提供这些方法的实现代码,编译器就会使用 object 类型中的实现代码,它们在类上下文中执行不一定正确。

string 类型

c#有string关键字, 在遮罩下转换为 .NET类 System.String。 有了它,像字符串连接和字符串复制这样的操作就简单了:

string str1 = "Hello";
string str2 = "World";
string str3 = str1 + str2;

尽管这是一个值类型的赋值, 但 string 是一个引用类型。 string 对象被分配在堆上,而不是栈上。 

因此,当把一个字符串变量赋予另一个字符串时,会得到内存中同一个字符串的两个引用。 但是,string与

引用类型的常见行为有一些区别。 例如, 字符串是不可改变的。 修改其中一个字符串, 就会创建一个全新的string对象, 

而另一个字符串不发生任何变化。

看看下面的代码

string s1 = "a string";
string s2 = s1;
Console.WriteLine("s1 is " + s1);
Console.WriteLine("s2 is " + s2);

s1 = "another string";
Console.WriteLine("s1 is now " + s1);
Console.WriteLine("s2 is now " + s2);


// 输出结果为
s1 is a string
s2 is a string
s1 is now another string
s2 is now a string

改变s1的值对 s2没有影响, 这与我们期待的引用类型正好相反。 当用值 a string 初始化 s1时, 就在堆上分配了一个新的 string对象。 在初始化 s2时,引用也指向这个对象, 所以 s2的值也是 a string。 但是当s1的值发生改变时,并不会替换原来的值,在堆上会新分配一个对象。 s2变量仍然指向原来的对象, 所以它的值没有改变。 这实际上是运算符重载的结果, 基本上 string类已经实现,其语义遵循一般的、直观的字符串规则。

字符串字面量放在双引号中 ("...") ;如果试图把字符串放在单引号中,编译器就会把它当成 char 类型,从而抛出错误。 

C# 字符串和char 一样,可以包含 Unicode 和 十六进制数转义序列。 因为这些转义序列以一个反斜杠开头,所以不能再字符串中使用没有经过转义的反斜杠字符,而需要用两个反斜杠字符 (\\)来表示它:

string filepath = "C:\\ProCSharp\\First.cs";

输入两个反斜杠字符会令人迷惑。 C#提供了替代方式。 可以在字符串字面量的前面加上字符 @ ,在这个字符后的所有字符都看成其原来的含义, 它们不会解释为转义字符:

string filepath = @"C:\ProCSharp\First.cs";
发布了27 篇原创文章 · 获赞 0 · 访问量 159

猜你喜欢

转载自blog.csdn.net/weixin_39328209/article/details/105511993