Func & Action 用法

2015年1月28日 星期三

Func & Action是委派用法,差別在於Func:有回傳值,Action:不需要回傳值

首先來看一下委派基本用法

 
    //委派基本定義
    public delegate string BaseDeletegate(string source);

    public static class ServiceBase
    {
        public static string Execute(BaseDeletegate action, string source)
        {
            string value = action.Invoke(source);
            return value;
        }
    }

    //呼叫委派用法
    public static void runBaseDeletegate()
    {
        BaseDeletegate action = ResponseMsg;
        string result = ServiceBase.Execute(action, "Neil");
        Console.WriteLine(result);
        Console.ReadLine();
    }

    //執行的方法
    public static string ResponseMsg(string str)
    {
        return "Hello:" + str;
    }
執行結果

改成用Func方法

 
    //Func定義
    public static string ExecuteFunc(Func action)
    {
        return action();  //有回傳值
    }

    //呼叫Func方法
    public static void runBaseFunc()
    {
        string result = ServiceBase.ExecuteFunc(() => {
            return ResponseMsg("FuncNeil");
        });
        Console.WriteLine(result);
        Console.ReadLine();
    }

    //執行的方法
    public static string ResponseMsg(string str)
    {
        return "Hello:" + str;
    }

執行結果:

改成用Action方法

 
    //Action定義
    public static void ExecuteAction(Action action)
    {
        action(); //沒有回傳值
    }

    //呼叫Action方法
    public static void runBaseAction()
    {
        ServiceBase.ExecuteAction(() => {
            ActionResopnseMsg("ActionNeil");
        });
    }

    //執行的方法
    public static void ActionResopnseMsg(string str)
    {
        Console.WriteLine("Hello:" + str);
        Console.ReadLine();
    }

執行結果:

Read more...

throw ex vs throw

2015年1月22日 星期四

寫了這麼久的程式,都沒特別注意到這二者的差別
簡單來說throw 會多一項原始執行錯誤行號。


  • throw ex resets the stack trace (so your errors would appear to originate from HandleException)
  • throw doesn't - the original offender would be preserved.


 
 static void Main(string[] args) {
  try {
   ThrowException1(); // line 19
  } catch (Exception x) {
   Console.WriteLine("Exception 1:");
   Console.WriteLine(x.StackTrace);
  }
  try {
   ThrowException2(); // line 25
  } catch (Exception x) {
   Console.WriteLine("Exception 2:");
   Console.WriteLine(x.StackTrace);
  }
 }

 private static void ThrowException1() {
  try {
   DivByZero(); // line 34
  } catch {
   throw; // line 36
  }
 }
 private static void ThrowException2() {
  try {
   DivByZero(); // line 41
  } catch (Exception ex) {
   throw ex; // line 43
  }
 }

 private static void DivByZero() {
  int x = 0;
  int y = 1 / x; // line 49
 }

輸出結果
Exception 1(throw):
at UnitTester.Program.DivByZero() in \Dev\UnitTester\Program.cs:line 49
at UnitTester.Program.ThrowException1() in \Dev\UnitTester\Program.cs:line 36
at UnitTester.Program.TestExceptions() in \Dev\UnitTester\Program.cs:line 19
Exception 2(throw ex):
at UnitTester.Program.ThrowException2() in \Dev\UnitTester\Program.cs:line 43
at UnitTester.Program.TestExceptions() in \Dev\UnitTester\Program.cs:line 25

Read more...

Group By 使用方法

2015年1月8日 星期四

最近遇到一個操作集合物件時,需要做群組的功能,以前都是在SQL裡操作

今天透過Linq的Group By方法來實作,順便記錄一下。


測試資料結構



Group By後結果



//放入測試資料
var testList = new List();
testList.Add("event1,s11,1");
testList.Add("event1,s12,1");
testList.Add("event1,s13,1");
testList.Add("event1,s14,1");
testList.Add("event1,s15,1");
testList.Add("event2,s21,1");
testList.Add("event2,s22,1");

//處理資料格式
var sourceList = new List>();
foreach (var item in testList)
{
    var querySplit = item.Split(',');
    string eventId = querySplit[0];
    string selectionId = querySplit[1];
    string handicap = querySplit[2];

    var list = new KeyValuePair(eventId, string.Format("{0}#{1}", selectionId, handicap));
    sourceList.Add(list);
}

//利用Group By 放入Dictionary物件裡
Dictionary> mList = sourceList.GroupBy(p => p.Key,p=>p.Value)
    .ToDictionary(p => p.Key, p => p.Select(s => s)
    .ToList());

最後呈現結果如下:

轉換完成後Dictionary的Key就是event,Value就是該Event下的記錄 。

參考來源:http://www.dotblogs.com.tw/lastsecret/archive/2011/02/18/21422.aspx

Read more...

傳值 vs 傳址

2015年1月5日 星期一

常常會搞不太清楚傳值以及傳址的差異,就先來筆記一下,以免以後忘記 開懷大笑

範例如下:

static void Main(string[] args)
{
//參考型別傳值(兩個變數位址不同)
TestClass y = new TestClass();
TestClass r1 = ChangeByVal(y);
Console.WriteLine("r1和y指向同實體:" + (r1 == y).ToString());
//參考型別傳址(兩個變數位址相同)
TestClass r2 = ChangeByRef(ref y);
Console.WriteLine("r2和y指向同實體:" + (r2 == y).ToString());
Console.ReadLine();
}
private static TestClass ChangeByVal(TestClass y)
{
y = new TestClass();
return y;
}
private static TestClass ChangeByRef(ref TestClass y)
{
y = new TestClass();
return y;
}


結果如下:

image

 

補充:這張圖可以說明兩個的不同處

pass-by-reference-vs-pass-by-value-animation

Read more...

使用var的場合

var 可用在暱名型別上,強型別或稱右(後)決議型別,只能做為宣告區域變數使用,一定要定義右邊的型態

編譯時期才做轉型



var x = new object();

//編譯時
object x = new object();


範例如下:



        
//使用var的場合
static void main(string[] args)
{
string[] words = { "apple","cherry","blueberry"};
var newwords = words.select(w => new { upper = w.toupper(), lower = w.tolower() });
foreach (var item in newwords)
{
console.writeline(item.lower + ":" + item.upper);
}
console.readkey();
}

Read more...