程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> C# 3.0 之新特性總結。

C# 3.0 之新特性總結。

編輯:.NET實例教程

一個不錯的博客,東東還多些!http://onlyzq.bokee.com


var alimama_pid="mm_10096109_566393_892989"; var alimama_titlecolor="0000FF"; var alimama_descolor ="000000"; var alimama_bgcolor="FFFFFF"; var alimama_bordercolor="E6E6E6"; var alimama_linkcolor="008000"; var alimama_bottomcolor="FFFFFF"; var alimama_anglesize="0"; var alimama_bgpic="0"; var alimama_icon="0"; var alimama_sizecode="11"; var alimama_width=760; var alimama_height=90; var alimama_type=2;

 
   
C# 3.0 之新特性總結
LazyBee
現在VS2008已經發布,而且很多人也都開始使用C# 3.0了,我在這裡對其新特性做一個總結,以方便自己日後或同仁參考:
1 隱式類型本地變量(var
這個和以前VB6中的全能類型var使用了同樣的名字,但在C#中,其實var不是一個實際類型,可以說是一個標記,就是讓編譯器去根據初始化的內容來確定需要使用的合適的類型。例如:var i = 5; 就等效於int i=5;
不過,隱式變量有以下幾個限制:
1 隱式本地變量的聲明必須同時包含一個初始化器。
2 初始化器必須是一個表達式,並且不能是對象或集合初始化器,但可以是包括new關鍵字以及對象或集合初始化器的組合表達式。例如:{1,2,3}是一個集合初始化器,如果你將其賦給一個隱式變量將出現編譯錯誤。(var x={1,2,3}; //錯誤),但是你可以這樣這樣var x=new List<int>{1,2,3};是允許的。
3初始化器表達式在編譯時不能為null.(例如:var i=null; //錯誤:不能為null)
4 由於是隱式本地變量,顧名思義,只能用於本地變量(在方法或屬性中使用的變量).
5 如果在隱式類型本地變量的初始化器的表達式中包含其他聲明變量(包括隱式類型的),那麼這些變量必須是相同(或者可以隱式轉換成相同)的編譯時類型。
例如:var arrayD = new[] { 1, "one", 2, "two" };// 錯誤,不允許混合類型
            var n = "Java"; var m = 4; var ff = m + n; //正確
注意:foreanch中使用也是允許的,如:
int[] numbers = { 1, 3, 5, 7, 9 };
foreach (var n in numbers) Console.WriteLine(n);
2 對象初始化器
    對象初始化器用於指定對象的一個或多個可訪問的字段或屬性的值,通過{和}進行封閉起來,多個字段賦值之間通過逗號分割。具體語法元素是:
Ø         對象創建表達式:
                  new 類型(類型參數可選)對象或集合初始化器可選
             new 類型 對象或集合初始化器
Ø         對象或集合初始化器:
                  對象初始化器
                  集合初始化器
Ø         對象初始化器:
                  {對象成員初始化器列表}
Ø         對象成員初始化器列表:
                  對象成員初始化器
                  對象成員初始化器列表,對象成員初始化器
Ø         對象成員初始化器:
                  標識符 = 初始化值
Ø         初始化值:
                  表達式
                  對象或成員初始化器
       注意:對象或成員初始化器是可以嵌套的,並且初始化器是不包含new關鍵字的。初始化器不能用於結構,初始化器中每個成員最多只能初始化一次。示例:



 1public class Point
 2    {
 3        public int X { get; set; }
 4        public int Y { get; set; }
 5    }
 6    public class Rectangle
 7    {
 8        Point p1 = new Point{ X = 1,Y = 2 };
 9        Point p2 = new Point{X=3,Y=3};
10        public Point P1 { get { return p1; } set { p1 = value; } }
11        public Point P2 { get { return p2; } set { p2 = value; } }
12}
13Rectangle r2 = new Rectangle() { P1 =new Point { X = 5, Y = 6 }, P2 = { X = 7, Y = 8 } };
14


請注意r2的初始化中的不同。
3 集合初始化器
    語法表示:
Ø         集合初始化器:
                  {元素初始化器列表}
Ø         元素初始化器列表:
                  元素初始化器
                  元素初始化器列表,元素初始化器
Ø         元素初始化器:
                  非賦值表達式

       示例:


 1List<int> digits = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
 2        public class Contact
 3            {
 4                string name;
 5               List<string> phoneNumbers = new List<string>();
 6                public string Name { get { return name; } set { name = value; } }
 7                public List<string> PhoneNumbers { get { return phoneNumbers; } }
 8        }
 9       &nbsp;var contacts = new List<Contact> { new Contact {Name = "Chris Smith",PhoneNumbers = { "206-555-0101", "425-882-8080" }},
10                              new Contact {Name = "Bob Harris",PhoneNumbers = { "650-555-0199" }}};
11


 


4匿名類型
    C#3.0允許將new和一個匿名對象初始化器一起來創建一個匿名類型的對象。具體語法格式為:
Ø         匿名對象創建表達式:
                  new 匿名對象初始化器
Ø         匿名對象初始化器:
                  {成員聲明器列表}
Ø         成員聲明器列表:
                  成員聲明器
                  成員聲明器列表,成員聲明器
Ø         成員聲明器:
                  簡單名稱
                  成員訪問
                  標識符=表達式(賦值表達式)
注:簡單名稱就是已經定義在當前范圍可訪問的標識符(變量名)。成員訪問就是通過“.”分割的表達式。
實例:
           Rectangle r = new Rectangle() { P1 = { X = 5, Y = 6 }, P2 = { X = 7, Y = 8 } };
         var anyType = new { Name = "Hello"/*賦值表達式*/, r.P1/*成員訪問*/};//匿名類型包含Name和P1兩個只讀成員
       var testType = new { r/*簡單名稱*/, i = 0 };//匿名類型包含r和i兩個只讀成員
注意:1 匿名類型中的成員都是只讀的。
      2 成員的類型根據賦值表達式來推導出實際類型(賦值表達式在編譯時不能為null),不能在代碼中指定成員類型。
3 如果兩個匿名類型創建表達式的成員變量名相同,並且經過推導出的變量的類型和順序也相同,那麼這兩個匿名類型對象是兩個同一匿名類
型的實例,例如:
            var p1 = new { Name = "Lawnmower", Price = 495.00 };
             var p2 = new { Name = "Shovel", Price = 26.95 };
   p1 = p2;
5 隱式類型數組
    隱式類型數組定義語法為:
Ø         數組創建表達式:
                  new [] 數組初始化器
    隱式類型數組實例的類型是根據數組初始化器推導出來的,所以這個數組初始化器只能包含確切的一種類型(也可以包含可以隱式轉換成這種類型的類型),而且這個類型不是null,否則將產生一個編譯錯誤。
       var a = new[] { 1, 10, 100, 1000 };                // int[]
     var b = new[] { 1, 1.5, 2, 2.5 };                  // double[]
     var c = new[] { "hello", null, "world"};           // string[]
   var d = new[] { 1, "one", 2, "two" };      &nb;       // 編譯錯誤,int和string不能進行隱式轉換,這種情況必須顯示的指定數組類型,如object[]
 隱式類型數組可以和匿名類型一塊使用來創建匿名類型的數據結構:如:
       var contacts = new[] { new {Name = "Chris Smith",PhoneNumbers = new[]{ "206-555-0101", "425-882-8080" }},
                        new {Name = "Bob Harris",PhoneNumbers = new[] { "650-555-0199" }}};
6 擴展方法:

  擴展方法是可以使用實例名來調用的靜態方法,是通過增加新的功能方法到已存在的類型中去的一種途徑。擴展方法必須是聲明在靜態類中的靜態方法,並且擴展方法的第一個參數必須帶一個this關鍵字,然後就可以通過第一個參數類型的實例進行調用,也就是可以象實例方法一樣調用。例如:
 


namespace LazyBee.UtilitIEs
{
    public static class Extensions
    {
        public static int ToInt32(this string s) 
        {    return Int32.Parse(s);}
        public static T[] Slice<T>(this T[] source, int index, int count) 
        {
            if (index < 0 || count < 0 || source.Length-index < count)    throw new ArgumentException();
            T[] result = new T[count];
            Array.Copy(source, index, result, 0, count);
            return result;
        }
    }
}


 


然後在你要調用擴展方法的地方導入LazyBee.UtilitIEs命名空間,就可以象如下方式調用:
string s = "1234";
 int i = s.ToInt32();                    // Same as Extensions.ToInt32(s)
 int[] digits = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int[] e = digits.Slice(4, 3);          // Same as Extensions.Slice(digits, 4, 3)
注意:
           1 實例方法優先於擴展方法的調用,也就是說只有不存在符合要求的實例方法,才會去查找時候存在擴展方法。
           2 擴展方法具有一般靜態方法所擁有的一切特性。
           3 擴展方法比實例方法具有更多的限制,以及更低的優先級。所以要盡量少用擴展方法,建議只有在不能增加實例方法的情況下使用。
           4 其他類型的擴展成員如屬性、事件、操作目前不支持,不過微軟正在考慮當中。
7 Lambda表達式:
       6.1 Lambda表達式提供一種更精簡的方式來寫匿名方法,其語法格式為:
Ø         表達式:
                     賦值表達式
                     非賦值表達式
Ø         非賦值表達式:
                     條件表達式
                     Lambda表達式
                     查詢表達式
Ø         Lambda表達式:
                     (Lambda參數列表可選)=>Lambda表達式體
                    隱式類型Lambda參數=> Lambda表達式體
Ø         Lambda參數列表:
                     顯式類型Lambda參數列表
                     隱式類型Lambda參數列表
Ø         顯式類型Lambda參數列表:
                     顯式類型Lambda參數
                     顯式類型Lambda參數列表,顯式類型Lambda參數
Ø         顯式類型Lambda參數:
                     參數修飾符可選 類型 標識符
Ø         隱式類型Lambda參數列表
                     隱式類型Lambda參數
                     隱式類型Lambda參數列表,隱式類型Lambda參數
Ø         隱式類型Lambda參數:
                     標識符
Ø    &n Lambda表達式體:
                     表達式
                     語句塊
示例:
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
        () => Console.WriteLine("OK"); //無參數列表
        (x,y) => x*y;                 // Multiple parameters
注意:1 如果是隱式類型,並且只有一個參數時,可以省略括號,如(x) => x + 1,可以簡寫成x => x + 1
2 隱式類型和顯式類型不能混合使用
6.2 當代理類型和Lambda表達式滿足下列條件時,我們說它們是兼容的,也就是可以將Lambda表達式賦值給該代理類型:
1 代理類型和Lambda表達式具有相通數量的參數;
2 如果Lambda表達式是顯式類型參數列表,那麼每一個參數的類型要和對應的代理類型的參數的類型和修飾符相同;如果是隱式類型參數列表,那麼代理類型中不能有ref和out的參數,根據Lambda表達式體推導出的參數類型要和代理類型的參數一致。
3 如果Lambda表達式體是一個語句塊,並且代理類型的返回值是void,那麼語句塊中不能包含有包含返回值的return語句;如果代理類型的返回值不是void,那麼語句塊必須是包含返回值的return語句,而且返回值的類型要和代理類型的返回值一致。
4 如果Lambda表達式體是一個表達式,並且代理類型的返回值是void,那麼表達式必須是能作為語句的表達式(只能是賦值表達式,對對象或函數的調用,new 表達式,變量的++,--操作表達式之一);如果代理類型的返回值不是void,那麼根據表達式推導出的類型必須能和代理類型的返回值類型一致。
示例:
public delegate R Func<T,R>(T t);
    public delegate void F2();
    public delegate R F3<T,R>(T t,R r);
  Func<int, int> a = x => x + 1;
    F2 b = () => Console.WriteLine("OK");
  F3<int, int> c = (x,y) => x*y;
下例將會出現編譯錯誤:
public delegate void F3<T,R>(T t,R r);
   F3<int, int> c = (x,y) => x*y;//Compile error: Only assignment, call, increment, decrement, and new object expressions can be used as a statement
6.3 當Lambda表達式傳遞給一個沒有指定類型參數的泛型方法時,.Net架構將根據表達式來推導出相應的類型參數,例如:
    public static class Extensions
     {
public static IEnumerable<S> MySelect<T, S>(this IEnumerable<T> source,Func<T, S> selector)
     { foreach (T element in source) yIEld return selector(element); }
     }
 var contacts = new[] { new {Name = "Chris Smith",PhoneNumbers = new[]{ "206-555-0101", "425-882-8080" }},
                            new {Name = "Bob Harris",PhoneNumbers = new[] { "650-555-0199" }}};
    IEnumerable<string> name = contacts.MySelect(j => j.Name);
   在這裡MySelect是一個擴展函數,所以contacts.MySelect(j => j.Name)運行時將翻譯成Extensions.MySelect(contacts,j => j.Name),在這裡T就是包含Name和電話號碼的匿名類型,所以S就是string 類型。
6.4 如果存在兩個相同名稱的帶有Lambda表達式為參數的方法,在隱式轉換過程中輸入參數和返回值的類型以最容易轉換為原則進行匹配,如:



class ItemList<T> : List<T>
     {
        public int Sum<T>(Func<T, int> selector)
        {
            int sum = 0;
            foreach (T item in this) sum += selector(item);
            return sum;
         }
         public double Sum<T>(Func<T, double> selector)
         {
             double sum = 0;
             foreach (T item in this) sum += selector(item);
             return sum;
          }
        }
       class Detail
        {
            public int UnitCount;
            public double UnitPrice;
            

        void ComputeSums() 
        {
            ItemList<Detail> orderDetails = GetOrderDetails();
            int totalUnits = orderDetails.Sum(d => d.UnitCount);
            double orderTotal = orderDetails.Sum(d => d.UnitPrice * d.UnitCount);
            
        }

 


 
 
7 Partial方法:
    在partial類中你可以聲明partial方法(就是方法前加了partial關鍵的的方法),主要是用於將方法的定義和簽名分開。這就為我們的類設計人員提供了類似於事件處理的方法鉤子,開發人員決定是否實現他,如果方法只提供了方法簽名,而沒有實現方法部分的定義,那麼編譯器會在編譯時移除掉該方法的簽名(包括調用該方法簽名的地方),不過partial方法必須滿足以下條件:
    1 該方法必須返回void.
    2 該方法沒有方法修飾符和Attribute應用。
    3 定義的方法和簽名必須完全匹配。

    

 


namespace PM

{

    partial class A

  &{

        partial void OnSomethingHappened(string s);

    }

    // This part can be in a separate file.

    partial class A

    {   // Comment out this method and the program will still compile.

        partial void OnSomethingHappened(String s)

        {

            Console.WriteLine("Something happened: {0}", s);

        }

    }

}

 



8 自動屬性
在我們定義類屬性時,特別是在定義值對象屬性時,通常該屬性對應的字段沒有其他用途,在這種情況下我們可以通過一種簡寫的方式來實現:
public class Point
{
   public int X { get; set; }
   public int Y { get; set; }
 }
這樣編譯器會自動生成private的字段,然後完成get和set的定義。
9 查詢表達式
       將在以後補上

原文地址:http://www.cnblogs.com/LazyBee/archive/2008/01/24/1051950.Html Google的搜索終於可以用了!大家試試! Google

博客廣告新思路!在你的博客裡放置廣告!我掛廣告了效果如下面所示!免費注冊擁有財富!
注冊地址
http://WWW.BLOGGAO.COM(點我就行)

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved