第七節:語法總結(1)(自動屬性、out參數、對象初始化器、var和dynamic等)

一. 語法糖簡介html

      語法糖也譯爲糖衣語法,是由英國計算機科學家彼得·約翰·蘭達(Peter J. Landin)發明的一個術語,指計算機語言中添加的某種語法,這種語法對語言的功能並無影響,可是更方便程序員使用。一般來講使用語法糖可以增長程序的可讀性,從而減小程序代碼出錯的機會。程序員

      須要聲明的是「語法糖」這個詞絕非貶義詞,它能夠給我帶來方便,是一種便捷的寫法,編譯器會幫咱們作轉換;並且能夠提升開發編碼的效率,在性能上也不會帶來損失。編程

      在編譯器發展早期,編譯器科學家門一直在千方百計的優化編譯器生成的代碼,這個時候,編譯器作的主要是對機器優化,由於那個時候機器的時間很是寶貴,機器運算速度也不快,今天咱們有了足夠好的機器了(但並非說咱們能夠不關注性能的編寫程序),並且做爲編寫軟件的人來講,比機器的時間寶貴得多,因此今天的編譯器也在向人優化了,從編程語言的發展之路來說,今天的編程語言比昨天的語言更高級,也更人性化了,咱們只要編寫更少的代碼,更符合人的思惟的代碼,而只要關注咱們值的關注的地方。體力活兒就交給編譯器吧。編程語言

二. 經常使用語法糖性能

1. 自動屬性優化

(1).  傳統的方式在類中聲明一個屬性,須要先聲明一個私有變量的字段,而後在配合公有屬性,以下面的:userId屬性。編碼

(2). 利用自動屬性:不須要字段,聲明一個空屬性,直接get,set(快捷鍵:prop),編譯時編譯器爲咱們生成存取數據的字段. 以下面的:userName屬性。spa

 1  public class userInfor
 2     {
 3         //私有字段
 4         private string _userId;
 5         //公有屬性
 6         public string userId
 7         {
 8             get
 9             {
10                 return _userId;
11             }
12             set
13             {
14                 _userId = value;
15             }
16         }
17 
18         public string useName { get; set; }
19 
20 
21         /// <summary>
22         /// 爲了後面的反射調用
23         /// </summary>
24         public void Test()
25         {
26             Console.WriteLine("我是一個方法");
27         }
28 
29     }

2. var和dynamiccode

(1). var類型:聲明變量的時候能夠不指定類型,由編譯器編譯的時候來指定類型。htm

  ①:必須在定義的時候初始化

  ②:必須是局部變量

  ③:一旦初始化完成,不能再給變量賦與初始值不一樣類型的值了,可是能夠賦相同類型的不一樣值.

  ④:var在效率是和使用強類型方式定義變量是同樣的

(2). dynamic類型:編譯期間不作任何檢查,運行期間才肯定類型。

  ①:定義的時候能夠沒必要初始化

  ②:能夠是全局變量,也能夠是局部變量

   dynamic在反射中的應用:經過反射拿到類後,賦值給dynamic類型,該類型的對象能夠直接點來調用方法

   缺點:dynamic在運行的時候才進行檢測,致使編譯的時候即便有錯誤也不會被發現; 不能用dynamic類型給肯定類型的變量進行賦值

 1  public class CompareTwo
 2     {
 3         //2. 可以使用的範圍
 4         // var b1 = 1;        //報錯,var必須定義在方法呃逆
 5         // dynamic b2 = 2;    //正常
 6         public static void Show()
 7         {
 8             {
 9                 //1. 初始化比較
10                 //var a1;         //報錯,定義的時候必須初始化
11                 //dynamic a2;     //正常
12             }
13             {
14                 //3. 賦值問題
15                 var c1 = 2;
16                 //c1 = "2";   //報錯,初始化完成不能賦值不一樣類型的變量
17                 c1 = 3;    //正常,初始化完成能夠賦值相同類型的變量的不一樣值
18 
19                 dynamic d1 = 2;
20                 d1 = "2";      //正常,運行時檢查進行類型指定,因此在編譯的時候不會報錯
21                 d1 = 3;       //正常
22 
23 
24                 var userInfor = new userInfor();
25                 userInfor.useName = "1";
26                 userInfor.userId = "2";
27                 // userInfor.fk123();    //報錯,編譯不經過
28 
29                 dynamic userInfor2 = new userInfor();
30                 userInfor2.userId = "1";
31                 userInfor2.useName = "ypf";
32                 //調用不存在的方法  (由於編譯的時候根本不檢查,因此不會報錯,運行的時候報錯)
33                 //userInfor2.fk123();    //編譯期間不報錯,運行的時候報錯
34 
35             }
36             {
37                 //4. dynamic在反射中的應用
38                 //4.1 常規反射調用方法
39                 Type type1 = typeof(userInfor);
40                 object oStudent = Activator.CreateInstance(type1);
41                 MethodInfo method = type1.GetMethod("Test");
42                 method.Invoke(oStudent,null);
43 
44                 //4.2 利用dynamic簡化調用
45                 //定義和編譯的時候能夠是任何類型,運行的時候進行轉換
46                 dynamic oStudent2 = Activator.CreateInstance(type1);
47                 oStudent2.Test();
48 
49             }
50         }
51     }

3. 可選參數

給方法的參數能夠指定默認值,若是在調用該方法的時候,不傳入該參數,則走默認值,傳入的話,則覆蓋默認參數.

(1).  有默認值的參數必須定義在沒有默認值的參數以後

(2).  默認參數必須是常量,不能是變量

(3).  ref和out參數不能指定默認值

1   public class OptionalParas
2     {
3         public static void Test(string useName,string userPwd,int userAge=16,string userSex="")
4         {
5             Console.WriteLine("userName:{0},userPwd:{1},userAge:{2},userSex:{3}", useName, userPwd, userAge, userSex);
6         }
7     }
1        //3.可選參數
2             Console.WriteLine("----------------------3.可選參數-------------------------");
3             OptionalParas.Test("ypf1", "123456");
4             OptionalParas.Test("ypf2", "654321", 56, "");

4. 對象(集合)初始化器

 1  public class ObjectInitilize
 2     {
 3         public static void Test()
 4         {
 5            
 6                 //一.對象初始化
 7                 //1. 傳統初始化對象的方式
 8                 userInfor uInfor1 = new userInfor();
 9                 uInfor1.userId = "1";
10                 uInfor1.useName = "ypf1";
11 
12                 //2.對象初始化器
13                 userInfor uInfor2 = new userInfor()
14                 {
15                     userId="2",
16                     useName="ypf2"
17                 };
18                 userInfor uInfor3 = new userInfor()
19                 {
20                     userId = "3",
21                     useName = "ypf3"
22                 };
23             
24                 //二. 集合初始化
25                 //1. 傳統方式
26                 List<userInfor> uList = new List<userInfor>();
27                 uList.Add(uInfor1);
28                 uList.Add(uInfor2);
29 
30                 //2. 集合初始化器
31                 List<userInfor> uList2 = new List<userInfor>(){
32                     uInfor1,
33                     uInfor2,
34                     new userInfor(){
35                         userId="4",
36                         useName="ypf4"
37                     }
38                 };
39                 
40         }
41     }

5. ref和out

兩者共同的使用場景,將ref或out參數傳入方法中,執行完方法後,能夠直接使用ref或out參數值。

  (1). ref必須在使用前賦值,即傳入方法前進行定義並賦值

  (2). out必須在方法中賦值而後使用,在調用方法前聲明兩個未實例化的變量,用來傳入和接收使用

舉例:有兩個int類型的值num1和num2,分別使用ref和out傳入對應的方法中,進行值交換。

 1  public class CompareRO
 2     {
 3         /// <summary>
 4         /// ref的使用
 5         /// </summary>
 6         public static void TestRef()
 7         {
 8             int num1 = 5;
 9             int num2 = 10;
10             Func1(ref num1, ref num2);
11             Console.WriteLine("num1的值爲:{0},num2的值爲:{1}", num1, num2);
12         }
13 
14         public static void TestOut()
15         {
16             int num1;
17             int num2;
18             Func2(out num1, out num2);
19             Console.WriteLine("num1的值爲:{0},num2的值爲:{1}", num1, num2);
20         }
21 
22         #region ref版參數值交換
23         public static void Func1(ref int n1, ref int n2)
24         {
25             int a = n1;
26             n1 = n2;
27             n2 = a;
28         }
29         #endregion
30 
31         #region out版參數值交換
32         public static void Func2(out int n1,out int n2)
33         {
34             n1 = 5;
35             n2 = 10;
36             int a = n1;
37             n1 = n2;
38             n2 = a;
39         }
40         #endregion
41 
42     }

6. 匿名類/匿名方法

 

   詳見:.Net進階系列(3)-匿名類、匿名方法、擴展方法

 

7. 擴展方法

 

   詳見:.Net進階系列(3)-匿名類、匿名方法、擴展方法

相關文章
相關標籤/搜索