C# typeof Gettype is as &拆箱 装箱

时间:2023-11-25 09:27:32

有时候,我们不想用值类型的值,就是想用一个引用。.Net提供了一个名为装箱(boxing)的机制,它允许根据值类型来创建一个对象,然后使用对这个新对象的一个引用。

首先,回顾两个重要的事实,1.对于引用 类型的变量,它的值永远是一个引用;2.对于值类型的变量,它的值永远是该值类型的一个值。

 int i = 5;
object o = i;
int j = (int)o;

这里有两个变量:i是值类型的变量,o是引用类型的变量。将i的值赋给o有道理吗?o的值必须是一个引用,而数字5不是一个引用,它使用整数值。实际发生的事情就是装箱:运行时将在堆上创建一个包含值(5)的对象,o的值是对该新对象的一个引用。该对象的值是原始值的一个副本,改变i的值不会改变箱内的值。

第3行执行相反的操作——拆箱。必须告诉编译器将object拆箱成什么类型。如果使用了错误的类型(比如o原先被装箱成unit或者long,或者根本就不是一个已装箱的值),就会抛出一个InvalidCastException异常。同样,拆箱也会复制箱内的值,在赋值之后,j和该对象之间不再有任何关系。

剩下的唯一问题就是要知道装箱和拆箱在什么时候发生。拆箱一般很明细的,因为要在代码中明确地显示一个强制类型转换。装箱则可能在没有意识的时候发生。如上面代码的第二行。但是,为了一个类型的值调用ToString,Equals或GetHashCode方法时,如果该类型没有覆盖这些方法,也会发生装箱。(同时,当你调用类型变量值的GetType()方法时,也会伴随着装箱的过程。如果处理为装箱形式的变量,你应该已经知道了具体类型,因此使用typeof替代即可。)别外,将值作为接口表达式使用时——把它赋值给一个接口类型的变量,或者把它作为接口类型的参数来传递——也会发生装箱。例如,Icomparable x = 5;语句会对5进行装箱。

之所以要留意装箱和拆箱,是由于它们可能会降低性能。同样这种性能损失通常不是大问题,但是还是应该值得注意。

针对typeof,getType is as 的一些代码

 public class Animal { }
public class Dog : Animal { }
 /// <summary>
/// typeof takes a type name(which yoy specify at compile time)
/// GetType gets the runtime type of an instance
/// is returns true if an instance is in the inheritance tree
/// </summary>
public void TestTypeOfAndGetType()
{
var dog = new Dog();
var result = dog.GetType() == typeof(Animal);
var result1 = dog is Animal;
var result2 = dog.GetType() == typeof(Dog); Console.WriteLine("dog.GetType() == typeof(Animal) :{0}",result);
Console.WriteLine("dog is Animal :{0}", result);
Console.WriteLine("dog.GetType() == typeof(Dog):{0}", result);
}
别外,关于as的,as运算符类似于强制转换类型操作,但是,因此,如果转换是不可能的,as返回null而不引发异常。下面两句代码是等效的:
expression as type
expression is type ? (type)expression : (type)null
下面是MSDN中的一个DEMO:
class ClassA { }
class ClassB { } class MainClass
{
static void Main()
{
object[] objArray = new object[6];
objArray[0] = new ClassA();
objArray[1] = new ClassB();
objArray[2] = "hello";
objArray[3] = 123;
objArray[4] = 123.4;
objArray[5] = null; for (int i = 0; i < objArray.Length; ++i)
{
string s = objArray[i] as string;
Console.Write("{0}:", i);
if (s != null)
{
Console.WriteLine("'" + s + "'");
}
else
{
Console.WriteLine("not a string");
}
}
}
}
/*
Output:
0:not a string
1:not a string
2:'hello'
3:not a string
4:not a string
5:not a string
*/