用《叩响C#之门》复习C#基础知识 第十一章
1、类型的判定
sizeof 运算符,用来获知数据类型在内存中占用几个字节 sizeof(数据类型)
typeof 运算符,用来获取数据类型的CTS类型名(CTS是通用类型系统) typeof(类型名)
GetType()函数,用于获取变量的类型,放在变量后 变量.GetOf()
2、命名空间
命名空间是用来组织类的,避免了重名的问题。.NET建议在大多数情况下,都至少提供两个嵌套的命名空间,第一个是公司名,第二个是技术名或软件名。这么做可以保证不会与其他组织编写的命名空间冲突。
namespace 公司名
{
namespace 技术名或软件名
{
…
}
}
或者
namespace 公司名.技术名或软件名
{
…
}
3、装箱与拆箱
装箱操作能把值类型数据打包到引用型变量,使我们能够像使用对象一样使用值类型变量。
对于装入箱中的数据,可以通过拆箱操作释放出来,拆箱操作要用显示装换。
在C#中,一切变量都可以看做是对象,所有值类型数据都可以通过隐式的装箱操作转换为引用型对象。当一个函数的参数类型不能确定时,装箱操作就非常有用。
4、对象的相等
Object类的三个“相等”成员函数 以及 相等运算符==
1)引用比较
ReferenceEquals() 是静态函数,用来测试两个引用符是否指向同一个对象,即两个引用符是否包含相同的内存地址。如果两个引用符指向同一个对象,函数返回true,否则返回false。如果两个引用符的值都是null,也返回true。
Object.ReferenceEquals()
public static bool ReferenceEquals (
Object objA,
Object objB
)
using System; class MyClass { static void Main() { object o = null; object p = null; object q = new Object(); Console.WriteLine(Object.ReferenceEquals(o, p)); p = q; Console.WriteLine(Object.ReferenceEquals(p, q)); Console.WriteLine(Object.ReferenceEquals(o, p)); } } /* This code produces the following output. True True False */
2)实例Equals()函数
在Object类中,实例版Equals()函数是一个虚函数,默认状态下只进行引用比较。但我们可以在派生类中重写该函数,实现值比较。如果两个对象是值类型,则判断两个值是否相等;如果两个对象是引用类型,则判断两个对象的数据成员是否相等。
public virtual bool Equals (
Object obj
)
参数
obj
与当前的 Object 进行比较的 Object。
返回值
如果指定的 Object 等于当前的 Object,则为 true;否则为 false。
using System;
public class Sample {
void Method() {
Object Obj1 = new Object();
Object Obj2 = new Object();
Console.WriteLine(Obj1.Equals(Obj2)); //===> false
Obj2 = Obj1;
Console.WriteLine(Obj1.Equals(Obj2)); //===> true
}
}
普通的值比较还是可以的,
using System; public class MyClass { public static void Main() { int a = 1; int b = 1; Console.WriteLine(a.Equals(b));//输出true Console.WriteLine(Object.Equals(a,b));//输出true } }以下试验有点奇怪,难道封装后,同样值的封装赋给不同的引用符,看到输出的值,得出结论:难道这两个引用符指向是一样的?!由此可以挖掘出:不同的字符串引用符,如果其后面赋值的字符串一样,则引用符指向同样的位置(该字符串不能通过+附加别的字符串,而是生成时就是一样的字符串) ,也就是说同样的字符串在内存中不会重复生成。另外,同样的值类型的同样的值,分别进行封装后,在内存中只会生成一个,所以不同的引用符必然也指向同一个地址。不同类型,即使值一样,封装后,依然放在不同的地址里,所以引用符指向也不会相同。
using System; public class MyClass { public static void Main() { int a = 1; int b = 1; long f = 1; object c = "1"; object d = b; object e = "1"; Console.WriteLine(a.Equals(b));//输出true Console.WriteLine(Object.Equals(a,f));//输出false Console.WriteLine(c.Equals(d));//输出false Console.WriteLine(Object.Equals(c, e));//输出ture Console.WriteLine(Object.ReferenceEquals(c,e));//输出true } }
3)静态Equals()函数
静态版Equals()函数的功能和实例版基本一样,实际上静态版Equals()函数通过调用实例版函数进行比较。
public static bool Equals (
Object objA,
Object objB
)
参数
objA
要比较的第一个 Object。
objB
要比较的第二个 Object。
返回值
如果 objA 是与 objB 相同的实例,或者如果两者均为空引用,或者如果 objA.Equals(objB) 返回 true,则为 true;否则为 false。
Equals 的默认实现仅支持引用相等,但派生类可重写此方法以支持值相等。
对于引用类型,相等定义为对象相等;即这些引用是否引用同一对象。对于值类型,相等定义为按位相等。ValueType 类支持值类型。
在调用 objA.Equals(objB) 前,此方法首先检查两个参数是否均为空引用。
using System; public class MyClass { public static void Main() { string s1 = "Tom"; string s2 = "Carol"; Console.WriteLine("Object.Equals(\"{0}\", \"{1}\") => {2}", s1, s2, Object.Equals(s1, s2)); s1 = "Tom"; s2 = "Tom"; Console.WriteLine("Object.Equals(\"{0}\", \"{1}\") => {2}", s1, s2, Object.Equals(s1, s2)); s1 = null; s2 = "Tom"; Console.WriteLine("Object.Equals(null, \"{1}\") => {2}", s1, s2, Object.Equals(s1, s2)); s1 = "Carol"; s2 = null; Console.WriteLine("Object.Equals(\"{0}\", null) => {2}", s1, s2, Object.Equals(s1, s2)); s1 = "Carol"; s2 = s1; Console.WriteLine("Object.Equals(\"{0}\", \"{1}\") => {2}", s1, s2, Object.Equals(s1, s2)); s1 = null; s2 = null; Console.WriteLine("Object.Equals(null, null) => {2}", s1, s2, Object.Equals(s1, s2)); } } /* This code produces the following output. Object.Equals("Tom", "Carol") => False Object.Equals("Tom", "Tom") => True Object.Equals(null, "Tom") => False Object.Equals("Carol", null) => False Object.Equals("Carol", "Carol") => True Object.Equals(null, null) => True */
4)相等运算符==
默认状态下,若两个对象为值类型,相等运算符“==”比较两个对象的值;若两个对象为引用类型,相等运算符“==”比较两个引用符,也可以重载运算符对其进行改变。
一般情况下,ReferenceEquals()函数进行引用比较,Equals()函数进行值比较,而相等运算符“==”则看情况,如果对象看起来像一个值,就把它设计成值比较,如果对象看起来不象值,就把它设计成引用比较。