首先,数据类型分为值类型和引用数据类型以及指针类型(暂不涉及):值类型是指直接储存在内存的栈上面,引用类型则在栈上储存一个引用,在堆上储存具体的值。
值类型分为内建类型和用户可以自定义的struct类型、enum类型,这些类继承于system.ValueType类,而system.ValueType继承于system.Object类,Object类是所有类的基类。
值类型如int、bool都是通常使用的别名,正式名为system.Int32、system.Boolean。
另外可以用var来命名一个变量,这样可以暂时不确定他的数据类型。
struct类似于JAVA中的分装类型,用于自定义一个类,可以包含不同的属性;
enum枚举类型相当于设定了一个数列,所建立的变量只能取值数列中的值,每个值自动默认对应从0开始的int值,但是可以手动强制从别的数开始或者强制为其他的数据类型。
举个栗子: days : short { monday = 5, tuesday, wenesday, thursday, friday, saturday, sunday }
struct和enum类型的定义要写在main方法体外!!!!结束没有分号!!!!
引用类型首先是三个内建类型:string、object、dynamic。其中dynamic强制规定类型检查在运行阶段而不是编译阶段。
string类型两种赋值方式可以得到相同的值,但是在底层的代价是不同的(两种方法:string a="abcdefg";string b="abcd";b+="efg"),建议使用第一种,第二种对系统需求的代价较大,需要经常修改的值可以使用stringbuilder类型获得可变长的内存空间。
重点:stringbuilder方法AppendFormat使用方法
StringBuilder s = new StringBuilder ();
s.AppendFormat("hello{1}{0}","ld","wor");
可以将s值赋值为helloworld。
接下来是class类型,class类可以包含成员变量和内部方法,默认的访问修饰符是private,外部不可访问,可以手动修改为public。C#的get set方法不是单独的方法而是使用关键字get set,直接调用get set关键字就可以使用对应的方法;静态方法绑定与class名,不可以用实例化的对象访问,而是用类名直接访问。
interface接口内部只能声明方法,没有具体的实现方法,子类中必须要实现接口中的方法。
abstract class抽象类是不能被实例化的,但是内部可以定义方法,子类可以默认的调用抽象类内部的方法,也可以在自身内部重写同名方法,实现方法的重载。接口不可以包含成员变量,抽象类可以具有自己的成员变量,并且被子类继承。
类的分类熟悉之后是类的转换,C#中的类型转换分为显示转换和隐式转换,C#是一种强类型的语言,在编译时会检查类型。
隐式转换适用于范围较小的类转为范围较大的类,不会有值的丢失,显示转换则适用于范围较大的类转换为范围较小的类,但是容易造成值得精度等丢失。
类型转换中有两个重要的关键字as,is。
is用于判断能否转换为一个类,输出结果为ture或者false,分别表示是否可以转换为目标类型,如果是ture,则可以使用as进行转换,但是as只能用于引用类型和非空类型,如果用于值类型的转换则会报错,因为在转换时由大类转为小类会赋值给小类一个空值,而值类型不可以为空。
值类型的转换可以使用convert类下的方法或者对应类下的parse方法或者TryParse方法,使用TryParse方法转化不能转化的值时会赋值一个默认值。还可以使用继承接口IConventible或TypeConventer来自定义自己得类型转化方法。
值类型和引用类型的互相转换通常称为装箱和拆箱,装箱属于隐式转换,不需要专门的语法,拆箱则可以通过显示转换实现。
拆装箱有一个常见的问题是不可为空的类型被赋值为空,这会报错,解决的方式可以在变量命名时变量名后加?来使得这个值可为空,同等意义的命名方法还有System.Nullable<int> i=10;这时这个i可以被赋值为空,但是读取时会报错,解决方法是使用HasValue来取值,为空则会返回false,或者使用方法GetValueOrDefalt,在空值是返回默认值。修改默认值可以使用双问号:int k=i ?? 20;则在i为空时赋值k为20,如果i有值则正常赋值。
接下来是数组,数组是一个引用类型,所有数组都继承于基类system.Array,这是一个抽象类,不能被实例化。
一维数组int[] numbers=new int[5];
二维数组int[,] numbers=new int[5,4];
数组的数组int[][] numbes=new int[5][4];
数组的数组又被称为交错数组,每一行可以有不同的长度。
以上都是固定长度的数组,所有数组的长度都是在定义时确定的,如果要使用变长的数组可以使用ArrayList数组列表,数组列表可以储存不同的类型,易引起混乱,建议使用List,List可以使用泛型规定内部的值类型。写法如下List<int> intList=new List<int>();这个列表中就只能使用int类型的值。
之上都是使用位置来访问列表中的值,而使用Hashtable哈希表可以自己定义每个值的key,Hashtable没有强制规定类型,如果需要强制规定,可以使用Dictionary来强制规定,写法如下Dictionary<string,string> d=new Dictionary<string,string>();强制规定了key和value都是string类型。Hashtable访问不存在的key时会返回一个空值,而在Dictionary中则会报错。但是Dictionary线程不安全,在多线程中建议使用ConcurrentDictionary。另外还有SortedList,会自动的根据key值对数组进行排序;stack数组先进后出的数组,类似于一个堆栈;queue是一个先进先出的数组。
然后是C#内的基础语法--逻辑语句
逻辑运算符和其他的语言并没有什么区别,比较特别的是在if判断之后的程序只有一行时可以省略大括号,但是出于编程习惯不建议使用。
比较有意思的一个循环方式是使用foreach循环,这是一个简便的写法,使用这一循环必须是集合类型实现了IEnumerable接口的才可以。
List<int> iss=new List<int>(){1,2,3};
foreach(int i in iss)
{
Console.WriteLine(i);
}
Console.ReadLine();
这样就循环输出了iss中的每个值。