有Java,C,C++基础,主要记录C#的差异之处,独特之处。
- 可空类型
- int等基础类型变量也可以被定义为空(null)
- 使用方式 int? x = null;
- 赋值给非可空类型时使用默认值 int y = x ?? 0;
- 泛型
- 定义,和C++, Java差不多,Stack<String> stack;
- List相当于C++的vector
- Dictionary相当于C++中的map
- 匿名方法
- 使用delegate(){ // code here};
- internal关键字
- 介于public,protected之间,可以被同一程序集内成员访问,简单理解一个exe,一个dll为同一程序集
- 迭代器
- 实现IEnumerator接口,即可使该类使用foreach等迭代器
- foreach(string item in list)
- 部分类
- public partial class Calculator
- 可以和原始类在编译时合并到一起
- 个人觉得,可以在不修改旧有类的情况下,给旧有类增加功能
- public partial class Calculator
- 垃圾回收,和Java相同,系统控制自动垃圾回收,代码中也可显式的调用垃圾回收。
- 语法
- 类似Java,Class结构
- static void Main() 入口,和C++差别是大小写,可以返回void或int
- 函数定义 [modifiers] return_type MethodName([parameters])
- 常量是静态的,但是不能用static来定义
- sbyte是有符号的8位,byte时无符号8位
- int永远是32位,所有类型位数都平台无关
- char和byte不同,需要显式转换
- 除float,double还增加了一种精度更高的浮点数,decimal,占用28个字节,多用于高精度的财务计算。使用时有性能损失
- decimal d = 12.34M;
- bool只能使用true,false,不能用0,非0等代替
- char在C#中为16位,Unicode字符
- 和Java一样,根类型为object
- Equals
- GetHashCode
- GetType
- ToString
- 关键字object其实是System.Object类的假名
- 有string类
- 字符串定义的时候加上@可以不做转义
- @“c:\xxxx\abc.txt”
- 不转义支持换行
- 字符串可以和基本类型直接+,因为所有类型都内置了ToString
- switch case,和c++略有不同
- case下有语句就必须有break
- 如果case下没语句,可以直接跟另一个case
- default可以放在最前面
- case支持字符串
- foreach
- 实现了IEnumerable接口的都可以用foreach
- 和C11的用法差不多
- 不能修改迭代中的变量,foreach(int x in arry){ x++; // wrong},for中可以修改
- 实现了IEnumerable接口的都可以用foreach
- 枚举
- 是一种基本类型
- 可以执行ToString,得到枚举的字符串名字
- 可以讲字符串转换为枚举类型 (TimeOfDay) Enum.Parse(typeof(TimeOfDay), "afternoon", true);
- 数组
- 可以在创建时不指定大小,动态大小,类似Java
- 命名空间
- 必须放在文件最开头
- 取别名:using Introduction = Wrox.ProCSharp.Basics;
- 可导出为文档的注释:/// <return>Resut</return>
- 预处理器简化了
- 不需分号结尾
- #define, #undef, #if, #elif, #else, #endif
- 支持 && ! == != 等运算符
- #warning, #errror, 编译时产生一些信息,提示某些变量是否关闭,如下
#if DEBUG && RELEASE #error "You've defined DEBUG and RELEASE simultaneously! " #endif
- #lpragma 取消、恢复一些编译警告
- 命名规则
- 如果需要使用关键字做变量,可以在定义时加上@
- 习惯规则
- 首字母大写
- 不使用_连接
- 常量和变量规则一致,不必全大写
- 首字母不大写的情况
- 私有变量
- 参数
- 变量同名的时候
- 不要使用关键字
- struct存储在栈上,class存储在堆上
- C#类
- 类函数成员组成
- 方法
- 不支持全局函数
- 声明方式类似Java
- 参数传递规则和Java一样,值传递,对象作为参数,传递了对象的引用值
- 强制引用传递
- 使用ref关键字
- static void SomeFunction(int[] ints, ref int i)
- 调用时也必须加上ref:SomeFunction(ints, ref i);
- 相当于C++中加上&
- 另一种专门用于传递返回值得输出变量,这样就可以不初始化传入的变量
- static void SomeFunction(out int i)
- int i; // note how i is declared but not initialized
- SomeFunction(out i);
- 支持重载,不支持默认参数
- 仅返回值不同不能算重载
- ref,out修饰了不能算重载
- 属性
- C++/Java中没有对应概念,来源于VB,比如窗体的width属性
private string somePropery public string SomeProperty { get { return "This is the property value"; } set { // do whatever needs to be done to set the property } }
- 可以使用public private修饰get,set
- 编译器会自动使用内联提高性能,无法代码控制
- 构造函数
- 后台创建的默认构造函数会将所有成员变量做初始化
- 特殊的静态构造函数
- 不可控的调用时机
- 保证只执行一次
- 不能带任何参数
- 只能访问类静态成员
- 同时可存在无参数非静态构造函数,不冲突
- 特殊的readonly字段,仅可在构造函数内赋值
- 支持静态,非静态
- 结构
- 于C++中稍有区别
- 必带默认构造函数,不允许自定义无参构造函数
- 存储于栈上
- 定义时需指定public等修饰
- 终结器,相当于C++的析构函数,但不能保证调用时机
- 方法
- 类函数成员组成
- 继承
- 同Java,不支持多继承,支持多接口
- 也是用virtual关键字表示可被子类重载,同C++不同于Java,默认函数都是非虚的
- 使用override关键字表示重载
- this代表自己,base代表基类,相当于Java中得super
- 新运算符,绝大部分和C++一样
- checked:检查数据类型溢出的,也可以使用编译选项/checked
- unchecked:参考上面一条,默认所有代码都是这个状态
- is:判断对象是否是某种类型
- as:类型转换用,相当于C++的dynamic_cast
- 委托和事件
- 对应C++中得函数指针,回调等内容
- 委托的定义
- 和函数定义相同,在最前面加上delegate关键字
- delegate double TwoLongsOp(long first, long second);
- 委托实际创建了一个类
- 使用TwoLongsOp method = new TwoLongsOp(object.method); method();
- 匿名方法,使用delegate
DoubleOp multByTwo = delegate(double val) {return val * 2;} multByTwo(2.0);
class MathsOperations { public static double MultiplyByTwo(double value) { return value*2; } public static double Square(double value) { return value*value; } }
- 多播委托
- 返回值必须是void
DoubleOp operations = new DoubleOp(MathOperations.MultiplyByTwo); operations += new DoubleOp(MathOperations.Square);
- 支持+, +=, -, -=等运算符
- 注意:多播委托的顺序不一定是加入顺序,要保证多个委托顺序无关
- 事件
- 类之间通讯用得机制,C++中不含本内容
- 添加事件处理函数:btnOne.Click += new EventHandler(Button_Click);
- 定义事件处理函数
- 按多播委托的方式处理
- 参数固定
- Private void Button_Click(object sender, Eventargs e)
- 使用匿名方法:btnOne.Click += new EventHandler(lblInfo.Text = "Button One was pressed";);
- 异常处理
- throw抛出异常
- try catch finally语句,同Java
- 指针
- C#支持指针,但只能在unsafe关键字圈起来的代码中使用
- 只支持基本类型,不能指向结构,类等涉及自动垃圾回收的对象
- 和C++中定义方式有些类似
- int* p1, p2, p3; // int *p1, *p2, *p3;这个是不合法的
- 指针可以理解为一种数据类型,所以和int等关键字放在一起