数组
注意下面的两种方式的赋值取值遍历的方式均不一样。
方式1
1 | int[][] newArray = { new int[] { 1, 3, 4, 5, 6 }, new int[] { 2, 4, 6, 8, 2 } }; |
初始化
1 | Dictionary<string, object> dic = new Dictionary<string, object> { |
方式2
二维数组的定义
1 | int[,] arr = new int[2, 5] { { 1, 2, 3, 5, 6 }, { 1, 2, 3, 4, 5 } }; |
JSON的转换
1 | int[,] arr = new int[2, 5] { { 1, 2, 3, 5, 6 }, { 1, 2, 3, 4, 5 } }; |
其中
1 | public static string ToJson(object t) |
三维数组
1 | int[,,] arr = new int[,,] { { { 1, 3 } }, { { 1, 2 } } }; |
Dictionary
Dictionary的描述
1、从一组键(Key)到一组值(Value)的映射,每一个添加项都是由一个值及其相关连的键组成
2、任何键都必须是唯一的
3、键不能为空引用null(VB中的Nothing),若值为引用类型,则可以为空值
4、Key和Value可以是任何类型(string,int,custom class 等)
示例
1 | // 去除重复的用户 |
List
包含
Any方法和All方法是比较常用
Any语义:任意一个元素满足条件则返回true,否则返回fase;
All语义:所有元素满足条件则返回true,否则返回false
判断ListA是否完整包含ListB
1 | bool IsContainsAll(List<Class> ListA, List<Class> ListB) |
排序
Sort
调用sort方法,如果需要降序,进行反转:
1 | List<int> list = new List<int>(); |
Sort+方法
使用lambda表达式,在前面加个负号就是降序了
1 | List<int> list= new List<int>(){5,1,22,11,4}; |
对于对象
1 | list.Sort( |
OrderBy
1 | list = list.OrderBy(o => o.Id).ToList();//升序 |
实现IComparable接口
1 | class People: IComparable<People> |
排序
1 | list.Sort(); |
多权重排序
排序的方法我就知道这么多了(其实有更多),接下来还有一个问题,如果希望当ID相同时比较Name,上面的代码就需要改改了。
其中,接口IComparable这样写:
1 | //重写的CompareTo方法,根据Id排序 |
IComparer和delegate还有lambda里可以这样:
1 | public int Compare(People x, People y) |
OrderBy方法有点不同:
1 | list = list.OrderBy(o => o.Id).ThenBy(o=>o.Name).ToList(); |
public new和new public
在变量上 new要写在public前面,方法上 new写在public 后面 。
public new
当基类和派生类都有Method2()时,派生类的对象会调用派生类的Method2()方法,而屏蔽基类的方法,不过编译器会warning;
当在派生类方法定义时,在修饰符public加上new,显式地屏蔽基类方法,此时编译器将不会报warning。
1 | public new void Method2() |
new public
嵌套类隐藏了基类中同名的类。使用 new
修饰符来消除警告消息。
1 | new public class NestedC |
抽象和虚拟
C#中抽象(abstract)和虚拟(virtual)的主要区别有:
抽象成员必须在抽象类中,而虚拟成员可以在非抽象类中。
抽象类不能被实例化,只能被继承。
虚拟成员允许在子类中被重写,实现多态。
抽象成员(抽象方法和抽象属性)必须在子类中被重写并实现,而虚拟成员在子类中可以不重写。
抽象成员不能有具体实现,只是一个签名,而虚拟成员在基类中必须有自己的实现。
抽象成员不需要使用任何关键字修饰符,而虚拟成员必须明确使用virtual关键字进行修饰。
子类实现抽象成员时必须使用override关键字,而重写虚拟成员可以使用override,也可以不使用。
抽象类不能被密封,而包含虚拟成员的类可以使用sealed关键字把该类密封,阻止被继承。
抽象成员用于表示子类必须实现的成员,而虚拟成员用于提供可以被重写的默认实现。
所以抽象要求子类必定重写,虚拟允许子类可选重写,二者在继承多态中的作用不同。
虚拟
在Java中父类的方法都可以被重写,而C#中必须设置为虚拟方法才能被重写
虚拟方法不要求类为抽象类
1 | class A |
抽象
抽象方法要求类必须为抽象类
抽象类不能实例化
1 | abstract class A |
抽象类和接口
抽象类和接口在C#中的主要区别有:
- 抽象类可以包含抽象方法和非抽象方法,而接口中所有的成员都必须是抽象的。
- 抽象类可以包含字段、属性、事件等成员,接口只能包含方法、属性、事件、索引器。
- 抽象类可以包含构造函数,而接口不能包含。
- 一个类只能继承一个抽象类,而一个类可以实现多个接口。
- 抽象类中的成员可以是不同的访问权限(public、protected等),接口的成员默认都是public的。
- 接口不能直接实例化,必须有类实现接口后才能实例化,抽象类可以实例化其非抽象子类。
- 抽象类表示对类层次结构的抽象,是一种模板设计,接口表示对行为的抽象,是一种行为的规范。
- 抽象类侧重设计整体框架,接口侧重设计细节归纳。
总结:
抽象类是对类的抽象,接口是对行为的抽象。
抽象类可以实现部分功能,接口全是抽象成员。
抽象类覆盖面宽,接口覆盖面窄。
一个类可以继承一个抽象类并实现多个接口。