c#6新功能

要:C# 6.0 新增功能

C#已經推進到6.0了,我想一些新的語法還是有必要了解一下,

C#6.0是roslyn編譯器所支援,而roslyn是被內建在VS2015,

雖然VS2013可以透過Nuget安裝Microsoft.Net.Compilers來使用C#6.0,

但可能會有未知的相容問題,所以想要使用C#6.0新功能建議是使用VS2015。

一、自動屬性初始化 Setting default values to Auto Properties

以往自動屬性初始值無法直接指定,必須要寫在建構函式,

現在可以直接對自動屬性設定初始值

public string Name { get; set; } = "Brooke";

而C#5.0以前,自動屬性必須包含get與set,

現在C#6.0允許你可以做自動屬性唯讀初始化

public string Name { get; } = "Brooke";

二、使用using 靜態命名類別

於C#6.0可以直接using 靜態命名類別,用法跟using命名空間很像,

只要是靜態類別,則可以使用 using static關鍵字,把類別當成命名空間來使用

using System;
using static System.Math;

namespace C_Sharp6
{
class Program
{
static void Main()
{
Console.WriteLine(Abs(-10));
Console.ReadKey();
}
}
}

三、String Interpolatin

以前string.Format舊的寫法

string name = string.Format("FullName:{0},{1}", m.FirstName, m.LastName);
而使用「字串插補」功能後,新的寫法,$"{變數}"

name = $"FullName:{m.FirstName} , {m.LastName}";
也就是說String.Format( "{0}{1}" , x , y );格式會被簡化成 $"{x}{y}";
我還看過有人還會在字串插補功能再加上if判斷式,蠻令人驚奇的。

var s = $"{m.FirstName} is {m.age} year{(m.age == 1 ? "" : "")} old";
範例如下

using System;

namespace C_Sharp6
{
class Program
{
static void Main()
{
Person m = new Person() { FirstName = "Lee", LastName = "Tom", age = 16 };

        string name = string.Format("FullName:{0},{1}", m.FirstName, m.LastName);
        name = $"FullName:{m.FirstName} , {m.LastName}";
        var s = $"{m.FirstName} is {m.age} year{(m.age == 1 ? "" : "")} old";

        Console.WriteLine(name);
        Console.WriteLine(s);
        Console.ReadKey();
    }
}
class Person
{
    public string FirstName;
    public string LastName;
    public int age;
}

}

四、Expression-bodied function members
於C#5.0以前成員還無法使用lambda運算式

using System;

namespace C_Sharp6
{
class Program
{
static void Main()
{
Person m = new Person() { FirstName = "Lee", LastName = "Tom", age = 16 };
Console.WriteLine(m.FullName);
Console.ReadKey();
}
}

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int age { get; set; }
    public string FullName { get { return FirstName + LastName; } }
}

}
但是現在C#6.0的成員已經可以使用lambda運算式了
1、屬性

using System;

namespace C_Sharp6
{
class Program
{
static void Main()
{
Person m = new Person() { FirstName = "Lee", LastName = "Tom", age = 16 };
Console.WriteLine(m.FullName);
Console.ReadKey();
}
}

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int age { get; set; }
    public string FullName => $"{FirstName}{LastName}";
}

}
2、方法

using System;

namespace C_Sharp6
{
class Program
{
static void Main()
{
Person m = new Person() { FirstName = "Lee", LastName = "Tom", age = 16 };
Console.WriteLine(m.FullName());
Console.ReadKey();
}
}

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int age { get; set; }
    public string FullName() => $"{FirstName}{LastName}";
}

}

五、索引初始設定式(Dictionary Initializer)
以前索引初始化都使用以下格式

var numbers = new Dictionary<int, string>()
{
{ 1, "tom"},
{ 2, "bob"},
{ 3, "tim"},
};
現在改為

var numbers1 = new Dictionary<int, string>()
{
[1] = "tom",
[2] = "bob",
[3] = "tim",
};
範例:

using System;
using System.Collections.Generic;

namespace C_Sharp6
{
class Program
{
static void Main()
{
var numbers = new Dictionary<int, string>()
{
{ 1, "tom"},
{ 2, "bob"},
{ 3, "tim"},
};

        var numbers1 = new Dictionary<int, string>()
        {
            [1] = "tom",
            [2] = "bob",
            [3] = "tim",
        };

        Console.WriteLine(numbers1[1]);
        Console.ReadKey();
    }
}

}

六、Null條件運算子
一般null條件判斷會這樣寫

private static int? GetFirstNameLength(Person person)
{
int? result = null;
if (person == null || person.FirstName == null)
{
return null;
}
result = person.FirstName.Length;
return result;
}
而現在可以用問號取代 == null ||,如person? ||,意思為如果person等於null時則||左邊為true;
也同義於問號取代 != null &&,如person? &&,意思為如果person不等於null時則&&左邊為true

using System;

namespace C_Sharp6
{
class Program
{
static void Main()
{
Person Person = new Person() { FirstName = "Lee", LastName = "Tom", age = 16 };
Console.WriteLine(GetFirstNameLength(Person));
Console.ReadKey();
}

    private static int? GetFirstNameLength(Person person)
    {
        int? result = null;
        //if (person == null || person.FirstName == null)
        //{
        //    return null;
        //}
        result = person?.FirstName?.Length;
        return result;
    }
}

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int age { get; set; }
    public string FullName => $"{FirstName}{LastName}";
}

}
上例GetFirstNameLength()的意思同於如果person為null時則直接回傳null,若否,

則繼續判斷FirstName是否為null,若是,則直接回傳null,若否,

則回傳FirstName的字串長度。

整個運作方式是如果左側為Null則整個運算式都是Null,

如果左側不是Null則會以點屬性表示,並成為結果。

再舉另一例子,請參考。

using System;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
//C#5.0之前
string data = "Some String";
var test = data != null ? data.Substring(0, 4) : string.Empty;
Console.WriteLine(test);

        //C#6.0之後
        string data2 = "Some String";
        var test2 = data2 != null ? data2.Substring(0, 4) : string.Empty;
        Console.WriteLine(test2);

        Console.ReadLine();
    }
}

}

七、nameof運算子

nameof運算子功能是回傳方法或是屬性的名稱,這功能配合try catch偵錯回傳訊息會非常有幫助。

using System;

namespace C_Sharp6
{
class Program
{
static void Main()
{
Console.WriteLine(nameof(GetName));
Console.ReadKey();
}

    private static string GetName()
    {
        return "tom";
    }
}

}
以下為回傳屬性名稱

using System;

namespace ConsoleApplication1
{
class SampleClass
{
public string ID { get; set; } = "A123456789";
public string Name { get; set; } = "Brooke";
}

class Program
{
    static void Main(string[] args)
    {
        var SampleClass = new SampleClass();
        Console.WriteLine("{0} : {1}" ,nameof(SampleClass.ID),SampleClass.ID);
        Console.WriteLine("{0} : {1}",nameof(SampleClass.Name),SampleClass.Name);
        Console.ReadKey();
    }
}

}

八、例外過濾
增加when語句來決定是否進入指定的catch區段,如下範例,當例外訊息包含了keyErrot字串時則另做處理,否則拋出例外

private static void CatchWhen()
{
try
{
var r = 0;
r = 0 / 0;
}
catch (Exception ex) when (ex.Message.Contains("keyError"))
{
Console.WriteLine("have handle exception");
}
catch (Exception ex)
{
throw;
}
}

九、例外使用非同步
於C#6.0 catch跟finally區段也能用await了,如下範例

using System;
using System.Threading.Tasks;

namespace C_Sharp6
{
class Program
{
static void Main()
{
CatchWhen();
Console.ReadKey();
}

    private static async void CatchWhen()
    {
        try
        {
            var r = 0;
            r = 0 / 0;
        }
        catch (Exception ex) when (ex.Message.Contains("keyError"))
        {
            Console.WriteLine("have handle exception");
            await Task.Delay(500);
        }
        catch (Exception ex)
        {
            throw;
        }
        finally
        {
            await Task.Delay(500);
        }
    }
}

}

posted @ 2016-01-28 15:11  冰封的心  阅读(257)  评论(0编辑  收藏  举报