C# 语法备查
数组和列表
数组的声明
int[] myArray=new int[4]{4,7,11,2}; int[] myArray=new int[]{4,7,11,2}; int[] myArray={4,7,11,2}; //上面3个都一样 string[] names = { "John", "Jackson", "Henry", "Jim" }; Programer[] ps = new Programer[] { new Programer(){ Name="张三", Language="C#", Position="Leader"}, new Programer(){ Name="李四", Language="C#", Position="Coder"} };
委托 Lamda和事件
//声明委托,可在namespace下 delegate double DoubleOp(double x); public delegate void Action<in T>(T obj); //实例化委托 GetString firstMeth=new GetString(someMeth); GetString firstMeth=someMeth; //也可以是委托数组 DoubleOp[] operations = { MathOperations.MultiplyByTwo, MathOperations.Square }; //使用委托 //直接执行 firstMeth(); //接受一个委托对象, static void ProcessAndDisplayNumber(DoubleOp action, double value) //多播委托 Action<double> operations = MathOperations.MultiplyByTwo; operations += MathOperations.Square; //自定义一泛型函数,接受一个泛型委托 static public void Sort<T>(IList<T> sortArray, Func<T, T, bool> comparison) { //使用 BubbleSorter.Sort(employees, Employee.CompareSalary); public static bool CompareSalary(Employee e1, Employee e2) { return e1.Salary < e2.Salary; }
x => x + 1 // Implicitly typed, expression body x => { return x + 1; } // Implicitly typed, statement body (int x) => x + 1 // Explicitly typed, expression body (int x) => { return x + 1; } // Explicitly typed, statement body (x, y) => x * y // Multiple parameters () => Console.WriteLine() // No parameters async (t1,t2) => await t1 + await t2 // Async delegate (int x) { return x + 1; } // Anonymous method expression delegate { return 1 + 1; } // Parameter list omitted
delegate int myDelegate(int i); public static int foobar(int i) { return i * i; } static void Main(string[] args){ myDelegate a = foobar;//直接使用委托 myDelegate b = delegate(int x) { return x * x; };//匿名方法 myDelegate c = x => x * x;//lambda表达式
事件
//在类CarDealer中 public event EventHandler<CarInfoEventArgs> NewCarInfo; //类中还有触发事件的函数 if (newCarInfo != null) { newCarInfo(this, new CarInfoEventArgs(car)); } //为事件添加handler var dealer = new CarDealer(); var michael = new Consumer("Michael"); dealer.NewCarInfo += michael.NewCarIsHere;
Expression-Bodied Members
用于方法
public void ShowString() => Console.WriteLine("This is a string");
等效于
public void ShowString() { Console.WriteLine("This is a string"); }
用于只读属性
private string AMem = "PlaceHolder"; public string ebm => AMem;
等效于
public string ebm { get { return AMem; } }
用于属性
public string Name { get => locationName; set => locationName = value; }
泛型
//泛型类 public class LinkedList<T> : IEnumerable<T> { //属性,也是一个泛型类型 public LinkedListNode<T> First { get; private set; } ....
public class DocumentManager<TDocument> where TDocument : IDocument{... //表示 TDocument必须实现接口IDocument //类似还有 Where T:struct 结构约束,T必须是值类型 //Where T:class 类约束,T必须是引用类型 //Where T:Foo 类型 T必须派生自基类Foo //Where T:new() T必须有一个默认构造函数
泛型接口 协变
//Rectangel 继承自Shape IIndex<Rectangle> rectangles //因为 接口IIndex 参数使用 out修饰 public interface IIndex<out T> //所以 IIndex<Shape> shapes = rectangles;//成立
泛型接口 抗变
//Rectangel 继承自Shape IDisplay<Shape> shapeDisplay... //因为接口IDisplay 参数使用in 修饰 public interface IDisplay<in T> //所以 IDisplay<Rectangle> rectangleDisplay = shapeDisplay; //成立
泛型方法
public static decimal Accumulate<TAccount>(IEnumerable<TAccount> source) where TAccount : IAccount { public static T2 Accumulate<T1, T2>(IEnumerable<T1> source, Func<T1, T2, T2> action) {
迭代
foreach
foreach 会调用in 后面对象的GetEnumerator方法,然后判断该enumerator的MoveNext方法返回为真,进行遍历。
总结:foreach中可以使用的对象。
1.自定义的包含返回IEnumerator的GetEnumerator方法。
public class HelloCollection { public IEnumerator<string> GetEnumerator() { yield return "Hello"; yield return "World"; } }
2.IEnumerable和IEnumerable<T>对象,因为
public interface IEnumerable<out T> : IEnumerable {、 IEnumerator<T> GetEnumerator(); }
yield return
只针对
IEnumerable
IEnumerable<T>
IEnumerator
IEnumerator<T>
等类型
使用yield的方法内部维护一个状态机,当yield return 返回时,函数好像被暂停。直到Enumerator 调用MoveNext,该方法继续运行。
注意:一旦使用yield ,代码块中就只能有yield return 和yield break,不能有return
一个例子:
public IEnumerable<string> Reverse() { for (int i = 3; i >= 0; i--) { yield return names[i]; } }
运算符
可空类型
如果一个或者2个都是null,结果为null
int? a = null; int? b = a + 4;//b为null
在比较可空类型时,只要有一个为null,结果都是false
空合并运算符
如果第一个操作数不是null,表达式就是第一个数的值,
如果第一个操作数是null,表达式是后面一个数的值。
int? c = null; int d = c ?? 10;//这里d为10
运算符重载
必须声明为public 和static,
//在结构体Vector内部 public static Vector operator +(Vector lhs, Vector rhs) { //使用 vect3 = vect1 + vect2;
索引
public string this[int index] { get{...} set{...} } public string this[string key] {....
全局异常
//Main函数开始的时候 Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); Application.ThreadException += Application_ThreadException;
添加处理函数
private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e) { MessageBox.Show(e.Exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); }
扩展方法
扩展方法包含在static类中,本身为static,第一个参数为this +类型,表示为该类型扩展。后面为方法的参数
下面将winform中Control 的所有子控件转成集合。
public static class LINQUtils { public static IEnumerable<Control> Children(this Control control) { foreach(Control c in control.Controls) { yield return c; } } }