Generic delegate กับ anonymous method (และ lambda expression)
posted on 04 Feb 2007 21:30 by tidno1 in csharp-and-dotnetหลาย ๆ คนคงได้ใช้ .NET 2.0 กันพอสมควรแล้ว น่าจะได้เห็น API ที่เพิ่มเข้ามาใหม่มากมาย
ใน class Array นั้นมี static method ใหม่ ๆ เพิ่มเข้ามามาก และส่วนใหญ่ก็จะเป็น generic method แล้วบาง method นั้นก็รับ parameter เป็น generic delegate ใหม่ ๆ เช่นpublic static T[] FindAll<T>(T[], Predicate<T>);
public static void ForEach<T>(T[], Action<T>);
public static bool TrueForAll<T>(T[], Predicate<T>);
public delegate TOutput Converter<TInput,TOutput>(TInput);
public delegate bool Predicate<T>(T);
ครับ Predicate ก็คือ method ที่คอยตรวจสอบค่า parameter ว่าเป็นค่าที่เราต้องการหรือไม่
ส่วน Action ก็คือ method ที่นำ parameter ไปทำอะไรซักอย่าง
ทีนี้ลองมาดูการใช้งาน method เหล่านี้กัน
Color[] pixels = GetPixels();
// C# 2.0 allow you do not need to create the delegate explicitly
// Color[] shadows = Array.FindAll(pixels, new Predicate(IsShadow));
Color[] shadows = Array.FindAll(pixels, IsShadow);
int[] argb = Array.ConvertAll(shadows, ToArgb);
}
bool IsShadows(Color c) {
return (c.R + c.G + c.B) / 3 < 96;
}
int ToArgb(Color c) {
return c.ToArgb();
}
int[] nums = GetErrorCode();
int[] negativeVals = ArrayFindAll(nums, IsNegative);
Array.ForEach(negativeVals, WriteLog);
}
bool IsNegative(int n) {
return n < 0;
}
void WriteLog(int n) {
Trace.WriteLine(n);
}
TextBox[] txtAddresses = GetAddresses();
return Array.TrueForAll(txtAddresses, HasText);
}
bool HasText(TextBox txt) {
return txt.TextLength > 0;
}
จะเห็นได้ว่าเราต้องเปลืองที่มาเขียน method สั้น ๆ ที่ไม่ได้ทำอะไรซักเท่าไหร่ เพื่อให้สามารถส่งไปเป็น parameter ของ method นั้นได้ (ตัวอย่างอาจดูงี่เง่าไปนิดหน่อย ก็อย่าไปสนใจมันเลยเนอะ)
ทีนี้ถ้าเราเอา anonymous method มาช่วยลดความยุ่งยากลง ก็จะได้ดังนี้
Color[] pixels = GetPixels();
Color[] shadows = Array.FindAll(pixels, delegate(Color c) { return (c.R + c.G + c.B) / 3 < 96; });
int[] argb = Array.ConvertAll(shadows, delegate(Color c) { return c.ToArgb(); });
}
int[] nums = GetErrorCode();
int[] negativeVals = ArrayFindAll(nums, delegate(int n) { return n < 0;});
Array.ForEach(negativeVals, delegate(int n) { Trace.WriteLine(n); });
}
TextBox[] txtAddresses = GetAddresses();
return Array.TrueForAll(txtAddresses, delegate(TextBox txt) { return txt.TextLength > 0; });
}
ถ้าเขียนด้วย lambda expression ใน C# 3.0 จะำได้ code ที่สั้นลงไปอีก
Color[] pixels = GetPixels();
Color[] shadows = Array.FindAll(pixels, c => (c.R + c.G + c.B) / 3 < 96);
int[] argb = Array.ConvertAll(shadows, c => c.ToArgb());
}
int[] nums = GetErrorCode();
int[] negativeVals = ArrayFindAll(nums, n => n < 0);
Array.ForEach(negativeVals, n => Trace.WriteLine(n));
}
TextBox[] txtAddresses = GetAddresses();
return Array.TrueForAll(txtAddresses, txt => txt.TextLength > 0);
}

แล้วจะเข้ามาเม้นต์ทำไมหว่า....
แหมเอาน่าไหนๆก็เข้ามาแล้ว....
ฝันดีแล้วกันเนาะ
#1 By NuNual on 2007-02-04 23:07