1. Class initialization method. When the class is initialized, the function of initializing attribute values is added. The following code.
Previous:
Person person = new Child(); person.Name = "Aomi"; person.Move();
New:
Person person = new Child() { Sex = "男", Name = "Aomi" }; person.Move();
2. Initialization method of collection class. The initialization of collection classes is no longer the monotonous way it used to be. You can add some values together during initialization.
Previous:
List<string> strList = new List<string>(); strList.Add("a"); strList.Add("b"); strList.Add("c");
New
List<string> strList = new List<string>() { "a", "b", "c" };
Introduction of keyword var
The types we often use in the previous chapters are all strong types. If you have used Javascript language, I believe you should understand about weak typing and strong typing. To put it simply, weak typing means that the type is difficult to determine when it is defined. Only when running will you know what type it is. C# is a strongly typed language, which means that you must know what type of data is defined when compiling. However, C# makes me confused on this point. Why do you say it like this? Take a look at the following piece of code.
var local = 1;
This code is a definition... All right. The author doesn’t know what to say either. There is relevant information that goes something like this. He's not without type. It is not a var type either. But it will be determined what type it is when compiling. When the above code is compiled, it is determined to be of type int. As shown in the picture below
, you can see the prompts in the picture above. It is a local variable int local. It clearly shows that it is an int type. During the development process, the author has never encountered the need to use the var keyword to declare variables. Therefore, the author has never understood in my heart - when should this be used? There is a little syntax to pay attention to here. I just mentioned that C# is a strongly typed language. Therefore, the var keyword must be given an initialized value when it is defined.
Due to the introduction of the var keyword, a way of writing class declarations emerged. Many books call them anonymous types. The following code
var student = new { Name="aomi", SNO="s0001"};
The introduction of the keyword dynamic
The author mentioned above that C# is a strongly typed language. The introduction of the keyword var is really difficult to understand. If the author says that it is a weak type, it seems that there is something wrong with C#. If it is a strong type and does not have the type var. I don't understand. Perhaps this is why C# introduced the keyword dynamic in 4.0. There is a brand new concept called dynamic typing. So what are dynamic types? Let’s first use the same method as the keyword var above to see what type it will look like when it is compiled. As shown in the picture below
it seems that the type is still dynamic during compilation. It seems that there are indeed dynamic types. Of course it doesn't work like this. We also need to take a look at how it looks when running. Just take a look at how visual studio debugs.
Set breakpoints first. Just click on the leftmost side of the writer (that is, where you write code) and a red dot will appear. That is the breakpoint. Eclipse seems to have a right-click option to set a breakpoint. Unfortunately, visual studio does not have it. You can only set breakpoints by right-clicking on the area where you write code. Readers, please try it yourself.
After the breakpoint is successfully set, start the (Debug mode) code. At this time we can monitor the variables we want to view. First select the corresponding variable and right-click. As shown below
When you click "Add Monitoring (W)", the corresponding monitoring form will pop up. Below is the author pulling out the corresponding form.
Okay. The next step is how to get him to take the next step. The tool buttons shown below will appear at the top of visual studio.
F5: Start
F10: Next step. Equivalent to eclipse's F5.
F11: Do internal code. Equivalent to eclipse's F6.
Shift+F11: Jump out. Equivalent to eclipse's F7.
Okay. I believe everyone should be able to debug it. Let's get down to business. From the monitoring form above, we can see the variable student status. The type is dynamic{int}. This way we can understand. Dynamic types are types that are determined at runtime.
The keyword dynamic is different from the keyword var because there is actually a dynamic type. So there is no need to initialize it when defining. Its corresponding type can be further determined at runtime. Don't bother trying it.
C#:
dynamic student = 1l; if (student is int) { Console.WriteLine("int类型"); } else if (student is long) { Console.WriteLine("long类型"); }
Parameter changes
We all know that the early methods have no corresponding default values. And the values must be passed in a defined order. C# has made some changes in this regard.
public static void mothed(string a,string b = "bbb") { }
我们可以看到代段里面参数string b = "bbb"上面的改变了。这就意味着在调用mothed这个方法的时候,可以不给参数b传值。他会用默认的值:bbb。但是参数a就必须传了。代码如下
第一种用法:这个时候参了的值是默认值(bbb).
mothed("aaa");
第二种用法:这跟以前的用法一样子。
mothed("aaa","ccc");
第三种用法:这新是一种用法。不用当然顺序的问题了。
mothed(b:"ccc",a:"a");
方法上的改变
不管是JAVA还是C#都有定义事件这个概念。那么C#是什么样子定义事件呢?
1.首先要用到关键字delegate声明该事件的委托类型。即是用于表示将来要发生事件的结构是什么。如要回返什么类型。会传入什么样子的参数类型。有几个参数。这些都可以开发人员自己定义。包括委托类型的名字。
public delegate void MoveHandler(object obj);
注意上面的代码可以独立一个cs文件来存放他。跟类的代码存放的级别一样子。
2.定义好了委托类型之后,我们就可以根据这个委托类型来声明对应的事件。关键字event就是表示当前为事件的意思。然后在Move方法触发对应的事件。判断事件是不是空的。如果不是就触发事件。
C#:
public class Child : Person { public event MoveHandler ChildMoveHandler; public Child() : base("Aomi") { } public override void Move() { if (ChildMoveHandler != null) ChildMoveHandler(this); } }
3.有了上面的代码的声明之后,我们就可以试用一下C#的事件了。如下面的代码。在child变量调用Move方法之前。笔者就给他初始化一个事件。这个时候他在调用Move方法,判断事件不为空就把自己传给了这个事件做为参数。而下面的事件代码(Child_ChildMoveHandler方法)里面会把对应的obj通过as功能转化为Child类的变量。在打印出名字来。请一定要注意给事件赋值的时候要用"+="。即是增加事件不是赋值哦。相反"-="表示删除事件。
C#:
class Program { static void Main(string[] args) { Child child = new Child(); child.ChildMoveHandler += Child_ChildMoveHandler; child.Move(); } public static void Child_ChildMoveHandler(object obj) { Child src = obj as Child; Console.WriteLine(src.Name); } }
对于上面的三个步骤是以前的用法。现在有了新用法。引入了关键字Action的用法。简单来讲就传递方法了。以前只能传递变量或是对象。现在方法也可以传递了。事件声明就变得很简单了。
C#:
public class Child : Person { public event MoveHandler ChildMoveHandler; public event Action<object> ChildActionMoveHandler; public Child() : base("Aomi") { } public override void Move() { if (ChildMoveHandler != null) ChildMoveHandler(this); if (this.ChildActionMoveHandler != null) this.ChildActionMoveHandler(this); } }
对于上面的三个步骤是以前的用法。现在有了新用法。引入了关键字Action的用法。简单来讲就传递方法了。以前只能传递变量或是对象。现在方法也可以传递了。事件声明就变得很简单了。
C#:
public class Child : Person { public event MoveHandler ChildMoveHandler; public event Action<object> ChildActionMoveHandler; public Child() : base("Aomi") { } public override void Move() { if (ChildMoveHandler != null) ChildMoveHandler(this); if (this.ChildActionMoveHandler != null) this.ChildActionMoveHandler(this); } }
使用的方式还是不变得。如下代码
class Program { static void Main(string[] args) { Child child = new Child(); child.ChildMoveHandler += Child_ChildMoveHandler; child.ChildActionMoveHandler += Child_ChildActionMoveHandler; child.Move(); } public static void Child_ChildActionMoveHandler(object obj) { Child src = obj as Child; Console.WriteLine(src.Name); } public static void Child_ChildMoveHandler(object obj) { Child src = obj as Child; Console.WriteLine(src.Name); } }
看吧。事件的定义变得很简单了。只是对于Action的用法。可能还是一点不了解。Action
public class Child : Person { public event MoveHandler ChildMoveHandler; public event Func<object,int> ChildFuncMoveHandler; public Child() : base("Aomi") { } public override void Move() { if (ChildMoveHandler != null) ChildMoveHandler(this); if (this.ChildFuncMoveHandler != null) this.ChildFuncMoveHandler(this); } }
执行代码:
class Program { static void Main(string[] args) { Child child = new Child(); child.ChildMoveHandler += Child_ChildMoveHandler; child.ChildFuncMoveHandler += Child_ChildFuncMoveHandler; child.Move(); } public static int Child_ChildFuncMoveHandler(object obj) { Child src = obj as Child; Console.WriteLine(src.Name); return 0; } public static void Child_ChildMoveHandler(object obj) { Child src = obj as Child; Console.WriteLine(src.Name); } }
显然不管是用Action关键字还是用Func关键字都是对方法的操作。但是在事件的声明上却变得更加的可读和简单了。至少不用在写声明委托类型了。既然对方法的操作。是不是可以这样了讲Action和Func可以定义为一个类内部的成员变量。当然可以。
public class Mothed { public Func<string, int> PrintFunc; public Action<string> PrintAction; public void Execute() { this.PrintFunc("PrintFunc aomi"); this.PrintAction("PrintAction aomi"); } }
看看执行代码吧
class Program { static void Main(string[] args) { Mothed mothed = new Mothed(); mothed.PrintAction = PrintAction; mothed.PrintFunc = PrintFunc; mothed.Execute(); } public static int PrintFunc(string value) { Console.WriteLine(value); return 0; } public static void PrintAction(string value) { Console.WriteLine(value); } }
很重要的一点:上面的事件是用“+=”,现在是用"="。即是赋值的意思了。
我们可以看到C#在把方法也变成一个可以使用的变量了。正因为这样子,在方法的赋值上出现俩种的方式写法。让我们看一下吧。
1.匿名方法赋值。
class Program { static void Main(string[] args) { Mothed mothed = new Mothed(); mothed.PrintAction = delegate(string value) { Console.WriteLine(value); }; mothed.PrintFunc = delegate(string value) { Console.WriteLine(value); return 0; }; mothed.Execute(); } }
2.lambda表达式赋值。
class Program { static void Main(string[] args) { Mothed mothed = new Mothed(); mothed.PrintAction = (string value)=> { Console.WriteLine(value); }; mothed.PrintFunc = (string value)=> { Console.WriteLine(value); return 0; }; mothed.Execute(); } }
本章总结
本章主要是讲到关于C#在语法上引入的一些新的特性。其中有一些还是值得我们去注意的。特别事件声明用的action和func。其次便是参数上的变化。这个笔者在开发过程也常常会用到。