C# 6.0 筆記

2016年12月7日 星期三

C# 6.0使用roslyn編譯器,而roslyn是被內建在VS2015,雖然VS2013可透過Nuget安裝”Microsoft.Net.Compilers”來使用C#6.0,但是不知道會不會有未知問題,所以還是建議使用VS2015來寫比較好。

 

1.Auto property enhancements (自動屬性初始化)

    class Student
    {
        public string Name { get; set; } = "Neil";

        public string Id { get; set; } = "A001";

        public DateTime DateCreated { get; private set; } = DateTime.Now;
    }

 

2.Expression-bodied funtion(成員使用lambda運算式)

    class Student
    {
        public string Name { get; set; } = "Neil";

        public string Id { get; set; } = "A001";

        public DateTime DateCreated { get; private set; } = DateTime.Now;

        //C# 6.0新增寫法
        public string GetStudentInfoNew => string.Format("Name:{0},Id:{1}", Name, Id);

        //一般寫法
        public string GetStudentInfoOld()
        {
            return string.Format("Name:{0},Id:{1}", Name, Id);
        }
    }

 

3.Using Static(使用Using 靜態命合類別)

using static System.String;//使用using static將string載入

namespace Csharp567
{
    public class Sample
    {
        public bool CheckIsNullNew(string val)
        {
            //不用string就可以直接使用IsNullOrEmpty方法
            return IsNullOrEmpty(val);
        }

        public bool CheckIsNullOld(string val)
        {
            return string.IsNullOrEmpty(val);
        }
    }
}

 

4.Null conditional operators(Null條件運算子)

public void GetStudentName()
{
    List<Student> students = null;
    students = new List<Student>() { new Student() { Name = "Neil", Id = "001" } };

    //新寫法
    if (students?[0]?.Name != null)
    {
        Console.WriteLine(string.Format("Name:{0}", students[0].Name));
    }

    //舊寫法
    if (students != null && students[0] != null && students[0].Name != null)
    {
        Console.WriteLine(string.Format("Name:{0}", students[0].Name));
    }
}

 

5.String interpolation(字串插補)

public void ShowString()
{
    string name = "Neil";
    int id = 1;
    //舊寫法
    string oldStr= string.Format("Name:{0},Id:{1}", Name, Id);
    //新寫法
    string newStr = $"Name:{Name},Id:{Id}";
}

 

 

6.nameof expressions(nameof運算子)

public void ShowStudentId()
{
    int studentId = 123;
    //用vs工具改名稱會一起更改
    string str = $"MethodName:{nameof(ShowStudentId)} ,{nameof(studentId)}:{studentId} Show Success!!";
    //result => ShowStudentId , studentId:123 Show Success!!
}

 

7.Index initializers(索引初始設定)

var studentsOld = new Dictionary<int, string>
{
    {1,"Neil" },
    {2,"Jeremy" }
};

var studentNew = new Dictionary<int, string>
{
    [1] = "Neil",
    [2] = "Jeremy"
};

 

8.Exception filters(例外過濾)

try
{
    var r = 0;
    r = 0 / 0;
}
catch (Exception ex) when (ex.Message.Contains("KeyeError")) //可filter自訂義條件
{

    Console.WriteLine($"msg: {ex.Message}");
}

Read more...

const vs readonly

2016年11月26日 星期六

 

1.const的常數是在編譯時期將所有使用到的地方替換成實際的數值(效能較好)

 

2.readonly是在實際執行期間才會去查找(靈活性高),可當做執行階段當數使用

例:public static readonly uint timeStamp = (uint)DateTime.Now.Ticks;

 

3.const的常數不能同時是static

 

4.readonly不能在method中使用

 

5.readonly可以在建構式裡給初始值

 

 

2016-11-26 下午 10-35-12

 

利用ILSpy反編譯工具查看編譯出來的dll

2016-11-26 下午 10-35-50

 

 

 

public class ReadOnlyTest
  {
     class SampleClass
     {
        public int x;
        // Initialize a readonly field
        public readonly int y = 25;
        public readonly int z;

        public SampleClass()
        {
           // Initialize a readonly instance field
           z = 24;
        }

        public SampleClass(int p1, int p2, int p3)
        {
           x = p1;
           y = p2;
           z = p3;
        }
     }

     static void Main()
     {
        SampleClass p1 = new SampleClass(11, 21, 32);   // OK
        Console.WriteLine("p1: x={0}, y={1}, z={2}", p1.x, p1.y, p1.z);
        SampleClass p2 = new SampleClass();
        p2.x = 55;   // OK
	//p2.y = 10; //因為不是在建構函數給值所以會出錯
	//錯誤訊息:無法指定唯讀欄位(除非在建構函數或變數初始設定式)
        Console.WriteLine("p2: x={0}, y={1}, z={2}", p2.x, p2.y, p2.z);
     }
  }
  /*
   Output:
      p1: x=11, y=21, z=32
      p2: x=55, y=25, z=24
  */

 

 

參考來源:

https://dotblogs.com.tw/yc421206/archive/2011/06/06/27232.aspx

http://slmtsite.blogspot.tw/2016/10/c-36-constant.html

https://msdn.microsoft.com/zh-tw/library/e6w8fe1b.aspx

https://msdn.microsoft.com/zh-tw/library/acdd6hb7.aspx

Read more...

String Pool

2016年11月22日 星期二

 

string pool簡單說就是一個Hash Table ,其中Key值是字串內容,Value是物件實體位置。

內容值會在程式編譯時期做初始設定,將程式碼中用到的用串加入,所以不同字串變數存放的靜態字串,

若是一樣的字串,字串會在編輯時期加入String Pool,透過String Pool的協助兩個變數會指到相同的物件實體。

 

一般的字串比對底層是以Byte為基礎的方式去比對,當比對的字串很長時,整個處理效能就跟著低落,若是可以善用

string pool,我們只需比對兩者是否指到相同的物件實體就可以了,可以獲得較佳的效能。

參考Larry大的文章,用ReferenceEquals效能是較好的。

 

2016-11-22 下午 11-29-52

執行結果

2016-11-22 下午 11-30-24

 

2016-11-22 下午 11-31-26

執行結果

2016-11-22 下午 11-32-18

2016-11-22 下午 11-34-13

執行結果

2016-11-22 下午 11-34-25

 

 

 

參考:https://dotblogs.com.tw/larrynung/archive/2011/06/30/30763.aspx

Read more...

TDD 安裝軟體準備事項

2016年5月23日 星期一


1.Visual Studio 2013
社群版下載位址
http://go.microsoft.com/fwlink/? LinkId=517284

2.VS套件
a.Specflow Visual Studio Extension – VS2013
https://visualstudiogallery.msdn.microsoft.com/90ac3587-7466-4155-b591-2cd4cc4401bc

b.Unit Test Generator
https://visualstudiogallery.msdn.microsoft.com/45208924-e7b0-45df-8cff-165b505a38d7
c.CodeMaid
https://visualstudiogallery.msdn.microsoft.com/76293c4d-8c16-4f4a-aee6-21f83a571496
3.NuGet 套件

  • Specflow
  • NSubstitute
  • Selenium WebDriver
  • Selenium WebDriver Support Classes
  • FluentAutomation
  • ExpectedObjects
  • Pickles.CommandLine


4.SQL
Visual Studio 2013以上版本內建localDB功能
說明 :https://msdn.microsoft.com/zh-tw/library/Hh510202(v=SQL.120).aspx

5.Fire Fox外掛
  • 因測試需要,建議您一定要安裝 Firefox 瀏覽器,並且安裝 Selenium IDE
6.Chocolatey
安裝套件

Read more...

TDD實務開發筆記

什麼是Unit Test

  1. 最小的測試單位
    粒度最小,以class來說指的是一個方法,
  2. 外部相依為零
    不應該與network、file、class相依
  3. 不具備商業邏輯
    不會有if else 之類的判斷
  4. 測試案例之間相依性為零
    這樣才可以精準的測試出哪個地方有問題
  5. 一個測試案例只測一件事
    不能跟其它案例有相依性,會影響測試結果

Unit Test 特性:First

  1. Fast:
    建議需低於500亳秒,高於1秒需要檢查是否有哪裡有問題,第一次起Test可能需要較久時間可排除
    若時間拉太長會影響開發節奏,讓開發速度變慢
  2. Independent:
    獨立性,不應該跟其它測試有相依性
  3. Repeatable:
    確保每次執行結果都一樣(在不改Code情況下)
  4. Self-validating:
    自我驗證,測試完後即可馬上看到結果,不需要經過query db或是查看檔案
  5. Timely:
    時效,通常都會開發好與測試的code一起commit,若不馬上做則會有偷懶的行為發生

3A原則

1. arrage
  • 初始化目標物件
  • 初始化方法參數
  • 建立模擬物件行為
  • 設定環境變數期望結果
2.act
  • 實際呼叫測試目標物件的方法
3.assert
  • 驗證目標物件是否如同預期運作


範例:

如果驗證以下的方法
public class MyCalculator
{
    public int Add(int first, int second)
    {
        return first + second;
    }
}






解法:





//先想好自已的Scenario
//例:傳入first:1,second:2,最後回傳值一定是3
[TestMethod()]
public void AddTest_First_1_Second_2_Should_be_3()
{
    //3A原則
    //arrange
    var target = new MyCalculator();
    var first = 1;
    var second = 2;
    var excepted = 3;

    //act
    var actual = target.Add(first, second);

    //assert
    Assert.AreEqual(excepted, actual);
    
}




Ms Test 相關簡介



Test 標記



  • Test Class :測試類別


  • Test Method:測試方法


驗證:



  • Assert(基本驗證):預期expected是否等是實際actual


  • CollectionAssert(集合驗證 ):一般陣列的驗證,好處不用用迴圈來一個一個驗證


  • ExceptedException(例外驗證):不能用try catch,所以要用專屬的驗證方式


Hook



  • ClassInitialize:每個測試類別開始前跑一次


  • ClassCleanup:每個測試類別結束前跑一次


  • TestInitialize:每個測試開始前跑一次


  • TestCleanup:每個測試結束後跑一次


  • AssemblyInitialize:整個測試專案開始前跑一次


  • AssemblyCleanup:整個測試專案結束後跑一次


  • TestContext:用WriteLine()即可印出


測試相關Attribute



  • TestCategory(assert excetipn) ==>分類tag


  • Ignore==>略過此測試方法


熱鍵


Ctrl+R+T:執行單一測試


Ctrl+R,Ctrl+T:偵錯單一測試


Ctrl+R+A:執行所有測試


Ctrl+R,Ctrl+A:偵錯所有測試

Read more...

自訂錯誤Exception

2016年5月19日 星期四

 

在處理Exception時,有很多種處理方式,這篇來講解的是自訂的Exception處理方法

應用情境:處理商業邏輯時,可以使用來自訂義錯誤的訊息。

 

初學者剛開始的寫法會是(圖一),自已throw 出exception,但是這樣會遇到,如果程式也發生錯誤的話會抓不到問題如圖二

而自訂義的錯誤則可以把二個行為分開,這樣可以確認到底是商業邏輯有問題,還是資料有問題(圖三、圖四)

 

其它有想到在來補充吧

1

(圖一)

2

(圖二)

3

(圖三)

4

(圖四)

 

參考來源:https://msdn.microsoft.com/zh-tw/library/ms229064.aspx

Read more...

用Oracle 使用TransactionScope錯誤訊息

2016年5月5日 星期四


在使用TransactionScope,要特別注意是否有安裝以下元件,不然會有以下錯誤訊息:
Exception type: System.InvalidOperationException
Message: The Promote method returned an invalid value for the distributed transaction.

需要檢查



原來是Oracle要安裝OracleMTSRecoveryService才可以使用。

Read more...

dateObj.getYear() vs dateObj.getFullYear()

2016年3月10日 星期四

 

今天遇到一個特別的情況,所以筆記一下

用Javascript的.getYear(),取出得到的是115

原來因為2000年的問題,getYear()只會回傳二位數,所以現在早就不能用了,要改用getFullYear()

 

 

 

參考來源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getYear

Read more...