大学学了C#,工作也是使用C#,虽然在日常的开发中没什么大的问题,但个人觉得在C#的理解还不是很清晰,所以决定花一定的时间来理一理学过的知识,顺便革新下脑袋里的知识,因为坑爹的学校在教.net的时候,是.net 2.0版本的,有点老古董了。哎,个人觉得是老师只会拖控件,而且对于新的.net版本他们应该很难去接受,所以挑选教材的时候,也不愿意去挑选自己不熟悉的新的.net版本。好了,也不吐槽学校和老师了,还是自己努力吧,因为老师毕竟教你了他们知道的。
1,类型
C#是一种强类型的语言。每个变量和常量都有一个类型,每个计算为值的表达式也是如此。 每个方法签名为每个输入参数和返回值指定一个类型。 .NET Framework 类库定义了一组内置数值类型以及表示各种逻辑构造的更复杂的类型,例如文件系统、网络连接、对象的集合和数组及日期。 典型 C# 程序使用类库中的类型,还使用为特定于该程序问题域的概念建模的用户定义类型。
思考一下,类型是干什么用的。其实不难发现,我们总是把我们需要的东西存储在用类型定义的变量上,如 int i=1,我们就把1存储在i变量所在的存储空间里,所以类型就是用来存储信息的。
类型可以存储的信息包括
- 该类型的变量所需的存储空间。
- 该类型可以表示的最大值和最小值。
- 该类型包含的成员(方法、字段、事件等)。
- 该类型所继承的基类型。
- 将在运行时为其分配变量内存的位置。
- 允许的运算种类行
当然我们使用类型的时候,是通过编译器,编译器为什么能够执行,是因为执行的代码是安全的,那么编译器是怎么确保执行的代码是类型安全的?例如,我们不可能把一个boolean类型的数据赋值给一个int类型的数据。这就可以想到:类型是存储信息的,所以编译器是通过类型存储的信息确保代码中执行的所有运算都是类型安全的。
其实编译器将类型信息作为元数据嵌入到可执行文件中。 公共语言运行时 (CLR) 会在运行时使用该元数据,以进一步确保它在分配和回收内存时类型安全。
2,在变量中声明指定的类型
在程序中声明变量或者常量的时候,必须指定类型或者使用关键字var让编译器可以识别到其类型。如下使用了一些类型和自定义的类型
Codefloat temperature;//float类型 string name;//string类型 MyClass myClass;//自定义类型 char firstLetter = ‘C‘;//char类型 var limit = 3;//var 定义的object类型,可千万别单纯的认为这个是int类型 int[] source = { 0, 1, 2, 3, 4, 5 };//数组,引用类型
在程序中,类型可以在方法参数和指定返回值中使用,看下面代码传入参数定义为了int类型,返回值是string类型
Codepublic string returnValue(int id){ return id+""; }
声明了一个变量后,不能使用新类型重新对它进行声明,也不能向它赋与它的声明类型不兼容的值。例如,不能声明 int,然后向它赋予布尔值 true。 但是,值可以转换为其他类型,例如将值赋给新变量或者作为方法参数传递时。 编译器会自动执行不会导致数据丢失的类型转换。 可能导致数据丢失的转换需要源代码内有强制转换。
2,内置类型
C#提供了一组标准的内置数值类型,用来表示整数、浮点值、布尔表达式、文本字符、十进制数值和其他类型。还有内置的string和object类型。我们可以在c#程序中可以很方便的使用这些类型
3,自定义类型
我们可以使用struck、class、interface和enum来创建我们自己自定义的类型。NET Framework 类库本身是 Microsoft 提供的自定义类型的集合,您可以在自己的应用程序中使用它们。 默认情况下,类库中最常用的类型在所有 C# 程序中均可用。 而对于其他类型,则仅当您显式添加定义这些类型的程序集的项目引用后它们才可用。 编译器拥有对该程序集的引用后,才可以在源代码中声明在该程序集中声明的类型的变量(和常量)
4,通用类型
(1)值类型
值类型派生自System.Object和System.ValueType.派生自 System.ValueType 的类型在 CLR 中有特殊行为值类型变量直接包含它们的值,这意味着内存在声明变量的任意上下文中都是以内联方式分配的。 值类型变量没有单独的堆分配或垃圾回收开销。
值类型分为两个类别:struct和enum。
内置值类型具有可以访问的属性和方法。如 byte b=Byte.MaxValue。我们也可以向值类型赋值,如int i=1;
我们也可以使用struct来创建自己的自定义类型。如
Codepublic struct Person{ int x; int y; public int say(int parms1,int parms2){ return parms1+parms2; } }
我们可以使用enum来定义一组常量,如
Codepublic enum number{1,2,3}
枚举类型主要是用来限制变量的可能性,如我们上面定义了枚举number,包含了123,三个int型,在使用number时,只能使用这3个数,不可能出现其他的数。
(2)引用类型
定义为类、委托、数组或接口的类型是引用类型.在运行时,当您声明引用类型的变量时,该变量会一直包含值 null,直至您使用 new 运算符显式创建对象的实例,或者为该变量分配已经在其他位置使用 new 创建的对象, 如
CodePeroson p1=new Person(); Person p2=p1;
接口必须与实现它的类对象一起初始化
创建对象时,将在托管堆上分配内存,变量只保存对对象位置的引用。对于托管堆上的类型,在 CLR 的自动内存管理功能(称为“垃圾回收”)对它们进行分配和回收时都需要系统开销。 但是,也对垃圾回收进行了高度优化,在大多数情况下它不会引起性能问题
所有数组都是引用类型,即使其元素是值类型也不例外.数组是从 System.Array 类隐式派生的,但可以通过 C# 提供的简化语法来声明和使用它们,如下面的示例所示:
Codeint[] num={1,2,3,4,5}; int len=num.Length;
引用类型完全支持继承.创建类时,可以从没有定义为 sealed 的任何其他接口或类继承,而其他类则可以从您创建的类继承并重写虚方法
5,文本值类型
在 C# 中,文本值从编译器接收类型。您可以通过在数字末尾追加一个字母来指定应如何类型化该数字文本。 例如,若要指定应按浮点数来处理值 4.56,则在该数字后追加一个“f”或“F”:4.56f。 如果没有追加字母,则编译器将为该文本推断一个类型。
6,泛型类型
一个类型可以通过一个或多个类型参数声明,而这些类型参数作为客户端代码在创建该类型的实例时提供的实际类型(具体类型)的占位符。这种类型称为“泛型类型”。 例如,.NET Framework 类型 System.Collections.Generic.List<T> 有一个类型参数,按照约定该类型参数的名称为 T。 在创建该类型的实例时,会指定列表将包含的对象的类型。如
List<int> list=new List<int>();
7,隐式类型
使用关键字 var隐式类型化一个局部变量(非类成员),该变量在编译时仍然会接收一个类型,但该类型是由编译器提供的
8,匿名类型
某些情况下为相关值的简单集合创建命名类型是不方便的,因为这些相关值不准备在方法边界外存储或传递。可以创建匿名类型来实现此目的。
9,可以为null的类型
普通的值类型不能有 null 值。但是,可以通过在类型后面附加 ? 来创建可以为 null 值的类型。 例如,int? 是一个也可以具有 null值的 int 类型。 在 CTS 中,可以为 null 的类型是泛型结构类型 System.Nullable<T> 的实例。 在向其数值可能为 null 的数据库传入数据和从中传出数据时,可以为 null 的类型尤其有用。
以上内容参考msdn的C#编程指南,仅仅为了学习,如有不妥,请指出。谢谢