ตอน 31 Implicitly typed local variables และ lambda expression

ไปหน้าแรก | สารบัญ | Laploy.comระเบียนบทความ | บทความจากลาภลอย

เว็บไซต์นี้เป็นตัวอย่างเนื้อหาบางตอนในหนังสือ "เรียนรู้ด้วยตนเอง OOP C# ASP.NET" ครอบคลุม บทที่ 1 ถึงบทที่ 6 (ในหนังสือมี 21 บท) เนื้อหาใน Blog อาจอาจแตกต่างจากในหนังสือเพราะเป็นเนื้อหาที่ยังไม่ได้ตรวจแก้ขัดเกลา (edit)

กดที่นี่เพื่อดูรายละเอียดเนื้อหาในแต่ละบท

กดที่นี่เพื่อไปยังเว็บบอร์ด ถาม-ตอบ 

 

Implicitly typed local variables

 

Implicitly typed local variables (ITLV) คือการใช้ keyword var เพื่อประกาศตัวแปร หรือสมาชิกแบบอื่นๆ โดยไม่ต้องกำหนด data type ซึ่งคล้ายการกำหนด type เป็น object (คือไม่ระบุ data type จริงๆ) หรือคล้ายการประกาศตัวแปรแบบ variant ในภาษา VB6

การใช้ ITLV ดีกว่าการกำหนด type type เป็นแบบ object เพราะเมื่อเรากำหนดให้ตัวแปรมี type เป็น object จะเกิดข้อเสียคือ ก่อนจะนำไปใช้งานได้ เราจะต้องทำ type casting หรือทำ boxing และ unboxing ก่อน ส่วนการใช้ variant อย่างในภาษา VB มีข้อเสียที่ใช้หน่วยความจำมาก และไม่เป็น strongly typed ซึ่งเป็นสิ่งสำคัญใน .NET

ปรกติในภาษา C#2.0 เมื่อเราต้องการประกาศตัวแปร เราจะเขียนแบบนี้

int foo;

หรือ

int foo = 1;

ดังนั้นรูปแบบของการประกาศคือ

<data type> <variable name> = <initializer> ;

จุดสำคัญคือต้องการให้ foo มี data type เป็น integer

การใช้ ITLV ในภาษา C#3.0 ช่วยให้เราสามารถประกาศตัวแปรในลักษณะนี้ได้

var foo = 1;

คำว่า var เป็น keyword ซึ่งทำหน้าที่บอกว่าตัวแปร จะมี data type เป็นเช่นเดียวกับ initializer ยกตัวอย่างเช่น

var foo = 1.2;

foo จะกลายเป็น decimal

var foo = “Good bye”

foo จะกลายเป็น string เป็นต้น

นอกจากนั้นเรายังอาจใช้ ITLV ร่วมกับ object initializes (ดูหัวข้อถัดไปในบทนี้)

ข้อสรุปเรื่อง Implicitly typed local variables
• คือการประกาศตัวแปรโดยไม่ต้องกำหนด type
• Initialize เป็นตัวกำหนด data type

 

Lambda expressions

lambda expression (ต่อไปจะเรียกย่อว่า LE) เป็นคุณลักษณ์ที่เพิ่มขึ้นใน C#3.0 มันทำให้ anonymous method ของ C#2.0 กลายเป็นสิ่งล้าสมัย LE มีประโยชน์ในการเขียนโค้ดที่เกี่ยวข้องกับ delegate, DLINQ และ expression tree LE ช่วยให้การเขียนโค้ดกระชับตามแบบภาษาในตระกูล C และสง่างามตามแบบ C# โปรดพิจารณาตัวอย่างโค้ดต่อไปนี้

x => x > 10

นี่คือ LE ในรูปสามัญที่สุด มันคือนิพจน์บูลลีนที่จะมีค่าเป็นจริงหาก x มีค่ามากกว่า 10 และจะมีค่าเป็นเท็จหากไม่เป็นเช่นนั้น เราสามารถใช้ LE ในภาษา LINQ ได้ หากใช้ภาษา DLINQ (DLINQ คือภาษาใหม่คล้าย LINQ ได้ถูกผนวกเป็นส่วนหนึ่งของ C#3.0 แล้ว) เมื่อคอมไพล์แล้วมักจะพบ LE ปรากฏอยู่ด้วย โปรดพิจารณาตัวอย่างโค้ด DLINQ ต่อไปนี้

var myQ = from myTable in orders, c in customers
where ( myTable.ShipCity == "London")
&& ( myTable.CustomerID == c.CustomerID)
select new {
myTable.OrderDate,
c.CompanyName,
c.ContactTitle,
c.ContactName };

โค้ดข้างบนคือการสืบค้นข้อมูลด้วยภาษา DLINQ ในโค้ดนี้จะเห็นว่ามีตารางสองตาราง อันแรกเป็น object ชื่อ myTable ซึ่งอยู่ภายใน object collection ชื่อ order อีกตารางชื่อ c อยู่ภายในฐานข้อมูลชื่อ customers เราใช้ภาษา DLINQ เพื่อสืบค้นข้อมูลพร้อมๆ กันทั้งสองตาราง โค้ดนี้เมื่อคอมไพล์แล้วจะเป็นดังนี้

var myQ = orders
   .Where(myTable => myTable.ShipCity == "London")
   .SelectMany(myTable => customers
      .Where(c => myTable.CustomerID == c.CustomerID)
      .Select(c => new { myTable.OrderDate,
      c.CompanyName,
      c.ContactTitle,
      c.ContactName }));

ในโค้ดข้างบนมีส่วนที่เป็น LE อยู่สองแห่งคือ

myTable => myTable.ShipCity == "London"

และ

c => myTable.CustomerID == c.CustomerID

ในสองบรรทัดนี้จะเห็นว่า LE อยู่ในรูปแบบ

parameters => expression

โดยบรรทัดแรก parameters คือ myTable ส่วน expression คือ myTable.ShipCity == "London"

C#3.0 ได้นิยาม generic delegate ไว้ให้แล้วจำนวนหนึ่งซึ่งมีรูปแบบดังนี้

delegate T Func<A, T>(A param)
delegate T Func<A0, A1, T>(A0 param0, A1 param1)
delegate T Func<A0, A1, A2, T>(A0 param0, A1 param1, A2 param2)
delegate T Func<A0, A1, A2, A3, T>(A0 param0, A1 param1, A2 param2, A3 param3)

ทำให้เราอาจนิยาม LE ใดๆ โดยไม่ต้องนิยาม delegate ก่อน เพียงใช้งานตามรูปแบบที่นิยามไว้แล้วดังแสดงข้างบน ยกตัวอย่างเช่น LE เพื่อตรวจสอบเลขคู่เป็นดังนี้

Func<int, bool> isEven = i => (i&1) == 0

ข้อสรุปเรื่อง lambda expression
• คือคุณลักษณ์ที่เพิ่มขึ้นใน C#3.0 เพื่อใช้แทน anonymous method ใน C#2.0
• ทำให้นิยาม delegate ได้กระชับขึ้น
• ใช้ร่วมกับภาษา LINQ

ตอนต่อไป Object และ collection initializes

Post a comment or leave a trackback: Trackback URL.

ความเห็น

  • λ  On สิงหาคม 30, 2007 at 4:28 pm

    เพิ่มเติมครับ Implicit type infference จะยังทำให้ C# ยังคงเป็น Type-safe language แต่ว่าไม่แนะนำให้ใช้ในการทำงานจริง เนื่องจาก feature นี้ถูกใส่เข้ามาเพื่อช่วยทำงานกับ linq โดยเฉพาะ ไม่มีประโยชน์อื่นเลย เนื่องจากคุณสมบัตินี้เป็นความสามารถของตัว compiler ในการ deduce var type ในขณะ compile time หลังจาก compile ผ่านไปแล้วจะไม่เกิดผลอะไรเป็นพิเศษ ในแง่ของ ตรรกะแล้วไม่มีความแตกต่างกันกับ explicit type
     
    และมันจะทำให้โค้ดของเราดูน่าปวดหัวมากๆ

ใส่ความเห็น

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / เปลี่ยนแปลง )

Twitter picture

You are commenting using your Twitter account. Log Out / เปลี่ยนแปลง )

Facebook photo

You are commenting using your Facebook account. Log Out / เปลี่ยนแปลง )

Google+ photo

You are commenting using your Google+ account. Log Out / เปลี่ยนแปลง )

Connecting to %s

%d bloggers like this: