專案裡有個在父類別宣告 virtual List<string> MyProp { get; } = new List<string>(); ,接著在子類別 override MyProp, Visual Studio 2017 自動帶出 List<string> MyProp => base.MyProp; 。(術語為 Expression Body Definition 運算式主體定義)

子類別要傳回 "Prod1","Prod2" ,我差一點就接改成 List<string> MyProp  => "Prod1,Prod2".Split(',').ToList();,仔細想想不對,我的本意是要給 MyProp 屬性初始值,沿用 => 寫法變成每次產生新字串陣列,意義不同,差點搞錯。為此趕緊寫篇筆記壓壓驚!

來個範例:

using System;
 
public class Blah
{
    private Guid _prop1 = Guid.NewGuid();
    public Guid Prop1
    {
        get
        {
            return _prop1;
        }
    }
    public Guid Prop2 { get; } = Guid.NewGuid();
 
    public Guid Prop3
    {
        get
        {
            return Guid.NewGuid();
        }
    }
    public Guid Prop4 => Guid.NewGuid();
 
}
 
static void Main(string[] args)
{
    var blah = new Blah();
    Console.WriteLine($"Prop1={blah.Prop1},Prop2={blah.Prop2}");
    Console.WriteLine($"Prop1={blah.Prop1},Prop2={blah.Prop2}");
    Console.WriteLine($"Prop3={blah.Prop3},Prop4={blah.Prop4}");
    Console.WriteLine($"Prop3={blah.Prop3},Prop4={blah.Prop4}");
    Console.Read();
}

在以上範例中,Prop1 與 Prop2 意義相同,都是物件建立時給予屬性初始值,屬性值固定不變;Prop3 與 Prop4 則偏向動態性質,每次呼叫時都重新產生新值。其中 Prop2 與 Prop4 是 C# 6.0 起支援的新寫法,較傳統寫法簡潔。

實測結果如下,Prop1/Prop2 兩次呼叫結果相同,Prop3/Prop3 每次讀取都會拿到新的 GUID。

Prop1=9a818bfa-7789-4dc3-8eab-a1c526cdf6c3,Prop2=d09ae5a4-01e8-41fa-a888-b508c974e463
Prop1=9a818bfa-7789-4dc3-8eab-a1c526cdf6c3,Prop2=d09ae5a4-01e8-41fa-a888-b508c974e463
Prop3=76e8b7ac-0830-4715-9d78-6840e7d59b3e,Prop4=922858c2-294c-4178-8a74-bd7bef385eb2
Prop3=1af010c8-a926-4e17-ad77-83d481227171,Prop4=03a8ea07-cc09-42fc-b37d-77c9d6c087d6

【延伸閱讀】

Comments

# by Alan

大大您好: 想請教一下,用以上的範例來說,如果是使用固定不變動的值,在頁面上取值的話,就結果來說的話好像是一樣的結果,這幾種用法有甚麼實質上的差異或使用上的考量嗎?

# by Jeffrey

to Alan, 不是很懂你的意思,像是 Prop3/Prop3 每次讀取都會拿到新的 GUID,應該不能用於固定不動的值。

# by Alan

抱歉沒有說明清楚,是說不是使用 "Guid.NewGuid();" 這類會在每次執行的時候產生新值,而是直接回傳一個 string 之類的固定值。 或者是像以下兩個範例: ``` A public class Point1{ private int x; public Point1(int x){ this.x = x; } public int X{ get{ return x;} } } ``` ``` B public class Point2{ public Point2(int x){ this.X = x; } public int X{ get; private set; } } ``` 在 new 完之後取得 X,就結果來說是一樣,不太理解這兩種寫法的差異以及會產生甚麼影響。

# by Jeffrey

to Alan, 在方法B內部如事後要修改X值,可以 void TestChangeX(int x) { this.X = x; },而方法A的話則是void TestChangeX(int x) { this.x = x; },差異不大,個人覺得方法B較簡潔。

Post a comment