类型、变量和值
C#是一种强类型语言,每一个变量和常量都是一个类型,每一个求指导表达式也是如此。每一个方法的签名指定了每一个输入参数和返回值的类型。Net类库定义了一组内置函数类型以及表达各种逻辑构造的更复杂类型(如文件系统、网络连接、对象的集合和数组以及日期)典型的C#程序使用类库中,以及对程序我呢提领域的专属概念进行建模的用户定义类型。
类型中可存储一下信息:
1、类型变量所需要的存储空间
2、可以表达的最大值和最小值
3、包含的成员(方法、字段、事件等)
4、继承自的基类型
5、在运行时分配变量内存的位置
6、允许执行的运算种类
内置类型:
C#提供了一组标准的内置数值类型来表示整数、浮点数、布尔表达式、文本字符、十进制值和其他类型的数据。还内置的string和object类型。
这些类型可提供给任何c#程序中使用,
自定义类型:
可以使用结构、类、接口和枚举构造创建你自己的自定义类型。net类库本身就是Mircrosoft提供的一组自定义的类型,以供你在自己的应用程序中使用。
值类型:
值类型时派生自System.ValueType(派生自System.Object).派生自System.ValueType的类型在CLR中具有特殊行为。值类型变量直接包含他们的值,这意味着在声明变量的任何上下文中内联分配的内存对于值类型变量,没有单独的堆分配或者垃圾回收开销。
值类型分为:结构和枚举
例如:byte b=byte.MaxValue;
引用类型:
定义类、委托、数组或者接口的类型都是引用类型。运行时,当声明引用类型的变量时该变量或i移植包含null,直至使用new运算符现实的创建对象,或者为该变量分配已经在其他位置使用new创建的对象,如:
MyClass mc=new MyClasss();
MyClass mc2=mc;
对于类型dynamic的简介:
C#4 引入了一个新的类型,该类型是一种静态类型,但是类型为dynamic的对象会跳过静态类型检查。大多数情况下,该对象就像具有类型object一样,在编译时,将假定类型转换为dynamic的元素支持任何操作。因此,不考虑对象是从COM API,从动态语言的角度从HTML文档对向模型(DOM)从反射还是从程序的其他位置获取自己的值,但是如果从代码无效,则在运行时会捕捉到错误。类型之间的转换非常的简单,这样开发人员将能够在动态类型和非动态类型之间切换。任何对象都可以隐式的转换为动态类型
如下:
dynamic d1 = 7;
dynamic d2 = "a string";
dynamic d3 = System.DateTime.Today;
dynamic d4 = System.Diagnostics.Process.GetProcesses();
反之,隐式转换也可以动态的应用于类型为dynamic的任何表达式;
使用类型为dynamic的参数重载决策
如果方法调用中的一个或者多个参数的类型为dynamic,或者方法调用的接收方的类型为dynamic,则会在运行时进行重载决策。
泛型编程
C#语言和公共语言运行时(CLR)的2.0版本中添加了泛型,泛型将类型参数的概念引入Net Framework,这样就可以设计具有以下特征的类和方法:在客户端代码声明并并初始化这些方法和类之前,这些类和方法会延迟指定一个或者多个类型。例如,通过使用泛型类型参数T,可以编写其他客户端代码能够使用的单个类。而不会产生运行时转换或者装箱操作的成本或者风险。
,使用Java泛型,实际上不会获得任何的执行效率,因为当你编译一个Java泛型类时,编译器会将所有的类型参数替换为Object。当然,如果你尝试建立一个List < int > , 你就需要对所有的int进行装箱。因此,这会有很大的开销。另外,为了让VM高兴,编译器必须为所有的类型插入类型转换。如果一个List是Object 的,而你想将这些Object视为Customer,就必须将Object转换为Customer,以让类型检查器 满意。而它在实现这些的时候,真的只 是为你插入所有这些类型转换。因此,你只是尝到了语法上的甜头,却没有获得任何执行效率。所以我觉得这是(泛型的)Java实现的头号问题。
第 二号问题,我觉得也是一个很严重的问题,这就是由于Java泛型是依靠消除所有的类型参数来实现的,你就无法在运行时获得一个和编译时同样可靠的表现。当 你在Java中反射一个泛型的List的时候,你无法得知这是个List什么类型的List。它只是一个List。因为你失去了类型信息,任何由代码生成 方案或基于反射的方案所产生的动态类型都将无法工作。唯一让我认为清晰的趋势就是,越来越多的东西将不能运行,就是因为你丢掉了类型信息。但在我们的实现 中,所有这些信息都是可用的。你可以使用反射 来获得List < T > 对象的System.Type。但你还不能建立它的一个实例,因为你并不知道T是什么。但是接下来你可以使用反射来获得int的Sytem.Type。然后你就可以请求反射将这两个System.Type结合起来并建立一个List < int > ,然后你还能获得List < int > 的另一个System.Type。因此,所有你在编译期间能做的在运行时同样可以。