เมธอดคือหน้าที่การงานของวัตถุให้เรียกใช้ 6. Method เมธอด นั้นหรือ คือ หน้าที่การทำงาน โปรแกรมจะทำงานได้ก็ต้องมีเมธอด แต่ที่ผ่ามมาก็ทำงานได้ โดยไม่รู้จักเมธอด นั้นเป็นเพราะเราได้ใช้งานเมธอดบ้างแล้ว เพียงแต่เราไม่รู้จักชัดๆ ว่านั้นมีเมธอดเราใช้งานอยู่ อย่างน้อยที่สุด เมธอด main( ) เมธอดเป็นพื้นฐานของการเขียนโปรแกรมเชิงวัตถุ เพราะวัตถุต้องมีหน้าที่การทำงาน การเรียนรู้เรื่องเมธอด เป็นเริ่มก้าวถึงการเขียนโปรแกรมเชิงวัตถุ เมธอด มีเรื่องราว มากมาย ที่เป็นพื้นฐาน ที่ควรทำความเข้าใจ ให้โปรแกรมทำงานได้ ดังได้กล่าวไว้แล้วว่า เมธอดคือหน้าที่การทำงานของวัตถุให้เรียกใช้ เมธอดคือหน้าที่การงานของวัตถุให้เรียกใช้ C# Programming with Visual C# 2010 Express
เป้าหมายการเรียนรู้ การนิยามเมทธอด ทั้งสเตติก และอินสแตทซ์เมทธอด เมทธอดโอเวอร์โหลด การใช้ตัวแปรเข้าแบบไดนามิกด้วยอะเรย์ ตัวแปรท้องถิ่น ในเมธอด การคืนค่าในเมธอด ตัวแปรทางเลือกของเมทธอด การเรียกเมทธอดด้วยการระบุชื่อตัวแปร การสร้างเมทธอดอัตโนมัติ กลไกการส่งตัวแปร และ แนวทางการใช้ตัวแปร การให้เมทธอดเรียกใช้ตัวเอง การเขียนภาษาซีชาร์ป เป็นเมทธอด เป็นเรื่องสำคัญที่จะเป็นกลไกสำหรับการเขียน่โปรแกรมเชิงโครงสร้าง ซึ่งเป็นรูปแบบการเขียนโปรแกรมที่จะถูกนำประยุกต์ใช้ต่อไปในการเขียนโปรแกรมเชิงวัตถุ สำหรับการสร้างและใช้งานเมทธอดประเด็นต่างๆ ที่เราจะได้เรียนรู้กันดังนี้ การนิยามเมทธอด มีการนิยามกันอย่างไร มีประเภทต่างๆ ของเมทธอดอะไรบ้าง การเรียกใช้เมทธอด การเรียกใช้เมทธอด แบบต่างๆ กัน เช่น การเรียกใช้เมทธอดที่มีการโอเวอร์โหลด ด้วยการส่งตัวแปรเข้าไม่เหมือนกัน หรือเรียกว่าลักษณะตามธรรมชาติของแต่ละเมทธอด (Signature) การสร้างเมทธอดที่คืนค่าได้ เมทธอดที่คืนค่าได้ แตกกับเมทธอดไม่สามารถคืนค่าได้ มีคำสั่งอะไรเป็นสำคัญ และเรียกใช้อย่างไร ส่วนใหญ่นิยมใช้เมทธอดที่คืนค่าได้กับหน้าที่การทำงานแบบใด การใช้ตัวแปรท้องถิ่น การรู้จัดใช้ตัวแปรที่ประกาศในเมทธอด กับตัวแปรที่ประกาศใน บล็อกของ statement ที่ขอบเขตการใช้งานอย่างไร การใช้ตัวแปร ทางเลือก แบบมีก็ได้ ไม่มีก็ได้ การเรียกชื่อเมธอด้วยด้วยการะบุชื่อตัวแปร เมื่อชำลำดับตัวแปรไม่ได้ เรียกชื่อมันเลย กลการการส่งตัวแปร และแนวทางการใช้เลือกใช้งาน ให้เหมาะสม เมธอดเรียกตัวเอง หรือ Recursive Method C# Programming with Visual C# 2010 Express
อะไรคือเมธอด เมทธอดคือกลุ่มของคำสั่ง ภาษาสมัยใหม่ทุกตัวใช้ แนวคิดเดียวกันนี้ เราอาจคิดเปรียบเทียบได้ว่า เมทธอดก็ คือ Function, Subroutine, Procedure, Subprogram เราจะสังเกตได้ง่ายๆ ว่าอะไรเป็นเมทธอด เมทธอด จะมีเครื่องหมาย วงเล็บ “( )” ต่อท้ายชื่อเมทธอด หน้าที่การทำงานมมีหลายแบบ แต่ละแบบ ทำลักษณะไม่เหมือนกัน บางที่ก็คล้ายกันแทนกันได้ บางทีเหมือนกัน แต่โปรแกรมพัฒนาแต่ตัวเรียกไม่เหมือนกัน ชื่อต่างๆ ที่อาจเคยพบได้ เรียกได้มีดังนี้ Function โดยทั่วไปเป็นหน้าที่การทำงานที่มีการคืนค่าได้ เช่นเรียกใช้แล้ว ส่งค่ามาให้ผู้เรียกใช้ด้วย Subroutine ก็เป็นที่การทำงาน ที่ไม่อาจคืนค่าหรือไม่คืนค่าก็ได้ แต่มันก็ทำงานตามคนเรียกใช้งาน Procedure ต่างกับฟังก์ชัน เพียง มันคืนค่าไม่ได้ อย่างน้อยที่คืนค่าได้คือคืนค่า void คือไม่คืนอะไรเลย SubProgram เป็นชุดรวม ที่มีอย่างน้อยหนึ่งหน้าที่การทำงาน นั้นหมายความว่าเป็น Module ก็ได้ สำหรับ เมธอด ใน C# แยกได้เป็น Function , Procedure (Void) เท่านั้น กล่าวซ้ำย้ำอีกที่ว่า เมธอดก็คือหน้าที่การทำงาน ที่ทั้งแบบคืนค่า และไม่คืนค่า ถ้าคืนค่าเรียก Function ถ้าไม่คืนค่า เรียก Void เราจะสังเกตได้ง่ายว่าเป็นเมธอดหรือไม่ได้ ด้วย การใส่วงเล็บหลังเมธอด เสมอ C# Programming with Visual C# 2010 Express
เมธอด Main( ) class Program { static void Main(string[] args) Console.WriteLine( “OK”); CheckEmpty( ); } private static void CheckEmpty() { } } สังเกตไหม เมธอด ทำไมต้องเป็น static ด้วย ศึกษาต่อไป ก็จะตอบคำถามนี้ได้ เมทธอดคือกลุ่มของคำสั่ง ภาษาสมัยใหม่ทุกตัวแนวคิดเดียวกันนี้ เราอาจคิดเปรียบเทียบได้ว่า เมทธอดก็คือ Function, Subroutine, Procedure, Subprogram เราจะสังเกตุได้ง่ายว่าอะไรเป็นเมทธอด เมทธอดจะมีเครื่องหมาย วงเล็บ “( )” ต่อท้ายชื่อเมทธอด ตัวอย่างในหน้านี้ ยกตัวอย่าง เมทธอด Main( ) ก็คือกลุ่มคำสั่งที่อยู่ในเมทธ่อด Main( ) ภายในเมทธอด Main( ) ก็สามารถมีการเรียกใช้เมทธอดอื่นๆ ได้ เช่น WriteLine( ), CheckEmpty( ) ในภาษา C# ทุกเมทธอดจะอยู่คลาส ซึ่งไม่เหมือนกับ C, C++, Visual C++ และ Visual Basic ที่สามารถสร้างเมทธอดนอกคลาสได้ ซึ่งจัดนี้เป็นเมทธอดประเภท Global เมธอด main เป็นจุดเริ่มต้นให้โปรแกรมทำงาน ดังนั้นจึงไม่มีใครสร้างมัน (ไม่เป็นออปเจ็กต์ที่ถูกสร้าง) มันจึงต้องทำงานได้เลย ด้วยการสร้างเมธอดนี้เป็น static C# Programming with Visual C# 2010 Express
การนิยามเมทธอด การตั้งชื่อ ชื่อไม่ควรเริ่มต้นด้วย ขีดล่าง ควรใช้อักษร พิมพ์ใหญ่นำหน้า และควรเป็นคำกริยา การใช้ตัวแปรเข้า จำนวนตัวแปรมีเท่าไหร่ก็ได้ ตัวแปร เข้าแต่ละตัวจะกำหนดชนิดข้อมูลของตัวแปรเข้าด้วย และ จะไม่มีตัวแปรเข้าเลยก็ได้ ทุกคำสั่งภายในเมธอด จะต้องอยู่ภายในเครื่องหมายปีกกา ถึงแม้จะคำสั่งเดียวก็ตาม เมธอดที่มีการคืนค่า ระบุชนิดข้อมูลการคืนค่าก่อนชื่อ เมทธอด และการคืนค่าเป็นชนิดข้อมูลอะไรจะต้องมีคำสั่ง return ภายในส่วนเมธอด เมธอดใดไม่คืนค่าชนิดข้อมูลอะไร ให้ใช้การคืนค่าเป็น void การนิยามเมทธอด ทำได้โดยนิยามใน 4 รายการต่อไปนี้ ชื่อ การสร้างชื่อจะต้องไม่ซ้ำกับชื่อตัวแปร ค่าคงที่ และชื่อสมาชิกอื่นๆ ของคลาสที่เมทธอดอยู่ และนิยมใช้อักษรตัวใหญ่นำหน้า ถ้าเป็นคำที่มีความหมายติดกัน ให้คำที่มีความหมายเป็นอักษรพิมพ์ใหญ่ เช่น ThisMethod( ) ตัวแปรเข้า ตัวแปรเข้าใส่ตามหลังชื่อเมทธอดภายในวงเล็บ จำนวนตัวแปรมีเท่าไหร่ก็ได้ ตัวแปรเข้าแต่ละตัวจะกำหนดชนิดข้อมูลของตัวแปรเข้าด้วย แต่เมธอดจะไม่มีตัวแปรเข้าเลยก็ได้ คำสั่งภายในเมทธอด จะต้องอยู่ภายในเครื่องหมายปีกกา ถึงแม้จะคำสั่งเดียวก็ตาม การคืนค่า มีสองแบบ คือ คืนค่าได้ กับ ไม่คืนค่า การคืนค่าได้ ต้องระบุชนิดข้อมูลที่จะคืนค่า หน้าชื่อเมธอด เช่น int MethodName( ) ถ้าไม่คืนจะต้องใส่คำว่า void นำหน้า เช่น void MethodName( ) C# Programming with Visual C# 2010 Express
การเรียกใช้เมธอด Static การเรียกเมธอด ทำได้โดยการเรียกชื่อเมธอดแล้วตามด้วย ตัวแปรเข้าให้ตรงกับที่ได้นิยามไว้ หรือไม่ต้องมีตัวแปรเข้า ในกรณีที่ไม่ได้นิยามตัวแปรเข้าไว้ แต่ยังคงต้องมีวงเล็บ ว่างไว้ ดังนั้นแล้วจะต้องมีวงเล็บเสมอ การเรียกเมธอดจากคลาสอื่น กรณี เป็น static method ทำได้โดยการเรียกชื่อคลาส แล้วตามด้วยชื่อเมธอดที่ต้องการของคลาสนั้น กรณี ไม่เป็น static method ทำได้โดยการเรียกชื่อ instance แล้วตามด้วยชื่อเม่ธอด การเรียกเมธอดจากคลาสอื่น แยกเป็นสองกรณีคือ กรณี เป็น static method ทำได้โดยการเรียกชื่อคลาสแล้วตามด้วยชื่อเมธอดที่ต้องการของคลาสนั้น คือไม่ต้องกสร้างเป็น ออปเจ็กต์ ก็เรียกใช้งานสมาชิกในคลาสนั้นได้ แต่ถ้าอยู่คลาสตัวเองก็ไม่ต้องเรียกชื่อคลาสตัวเอง กรณี ไม่เป็น static method ทำได้โดยการเรียกชื่อ instance หรือชื่อออปเจ็กต์ที่สร้างไว้ แล้วตามด้วยชื่อเมธอด class Program { public int A( ) { } public static void B( ) { } public static void main( String[ ] args) { Program p = new Program( ); //สร้าง instance p.B( ); // ต้องสร้างเป็น Instance ก่อน จึงเรียกเมธอด ผ่านชื่อ instance A ( ); // เรียกได้เลย } สำหร้บการกสร้างออปเจ็กต์อาจยังอาจไม่เข้าใจ อะไรมากนั้น รอให้เรียนถึงเรื่องคลาสก่อน C# Programming with Visual C# 2010 Express
การเรียกเมธอดจากต่างคลาส class Program { public static void main( String[ ] args) { Example ex = new Example( ); // ต้องสร้างเป็น Instance ก่อน จึงเรียกเมธอด ผ่านชื่อ instance ex.C( ); Example. D( ); // เรียกผ่านชื่อคลาสได้เลย } Class Example public int C( ) { } public static int D ( ) { } ตัวอย่างนี้ เป็นการเรียกเมธอดจากต่างคลาส ซึ่งคือคลาส Example มีสมาชิก สองตัว คือ เมธอด C กับ D แต่เมธอด D เป็น static ยังคงใช้หลักการเรียกแบบหน้าสไลด์ที่ผ่านมา การเรียก จากต่างคลาส จะต้องสร้างเป็นออปเจ็กต์ใหม่ขึ้นมาก่อน เช่น ในเมธอด main จะสร้างออปเจ็กต์ใหม่ชื่อ ex การเรียกจากต่างคลาส จึงเรียกเมธอดจากชื่อ ออปเจ็กต์ใหม่ เช่น ex.C( ); ยกเว้นเมธอดนั้นเป็น static จะเรียกจากชื่อคลาสได้เลย เช่น Example.D( ); C# Programming with Visual C# 2010 Express
การคืนค่าของเมทธอด การประกาศเมทธอดเป็นชนิดไม่มี void Key word : return การประกาศเมทธอดเป็นชนิดไม่มี void เมทธอดชนิดไม่มี void จะต้องมีการคืนค่าเสมอ การเพิ่มคำสั่งคืนค่าด้วย return static int TwoPlusTwo( ) { int a,b; a = 2; b = 2; return a + b; } คำสั่ง return จะทำให้โปรแกรมออกจากทำงานทันทีดังที่รู้แล้ว นอกจากนี้ยังสามารถใช้เพื่อคืนค่าจากเมทธอดได้ด้วย การคืนค่าของเมทธอดทำได้ดังนี้ ประกาศเมทธอดเป็นชนิดไม่มี void เพิ่มคำสั่ง return ภายในเมทธอด ระบุค่าที่จะส่งออก ตัวอย่าง เมทธอดที่ไม่เป็น void และมีการคืนค่าชนิดข้อมูล int class ExampleReturningValue{ static int TwoPlusTwo( ){ int a,b; a = 2; b = 2; return a + b; } static void Main( ){ int x; x = TwoPlusTwo( ); Console.WriteLine(x); C# Programming with Visual C# 2010 Express
การใช้คำสั่ง Return Return ทันที Return แบบมีเงื่อนไข static void ExampleMethod( ){ Console.WriteLine("Hello"); return; Console.WriteLine("World"); } static void ExampleMethod( ){ int numBeans; //... Console.WriteLine("Hello"); if (numBeans < 10) return; Console.WriteLine("World"); เราสามารถใช้คำสั่ง return เพื่อให้โปรแกรมออกจากเมทธอดได้ทันที่ที่เจอคำสั่ง return หากไม่มีคำสั่ง return โปรแกรมจะทำงานตามปกติ จนจบสั่งสุดท้ายของเมทธ่อด ดังตัวอย่างต่อไปนี้ static void ExampleMethod( ){ Console.WriteLine("Hello"); return; Console.WriteLine("World"); } การใช้คำสั่ง return แบบนี้จะไม่มีประโยชน์เพราะคำสั่ง Console.WriteLine(“World”) จะไม่ได้ทำงานเลย ซึ่งคอมไพเลอร์จะจะแสดงข้อความเตือนว่า “Unreachable code detected” การใช้คำสั่ง return ออกระหว่างทางแบบมีเงี่อนไข เป็นวิธีที่พอเห็นใช้กัน และมีประโยชน์กว่า เงื่อนไขการออกจากโปรแกรม เช่น if, switch การ return กับค่าข้อมูล ใช้กับเมทธอด ที่ไม่มีคำนำหน้าว่า void ซึ่งจะมีเรียนอีกในตอนต่อไป C# Programming with Visual C# 2010 Express
การใช้ตัวแปรท้องถิ่น (Local Variable) สร้างภายในเมทธอด เป็นของเมทธอดใช้ หายไปเมื่อเมทธอดจบการทำงาน ตัวแปรที่ใช้ร่วมกันในเมทธอด ต้องเป็นตัวแปรระดับสมาชิกของคลาส ขอบเขตตัวแปรขัดกัน ตัวแปรท้องถิ่นกับตัวแปรระดับสมาชิกของคลาสที่ใช้ชื่อ เหมือนกัน แต่ละเมทธอดมีชุดตัวแปรของตนเอง และใช้ได้เฉพาะตัวแปรของตนเอง เมทธอดอื่นจะร่วมใช้ไม่ได้ รวมทั้งที่ใดๆ ของโปรแกรมจะร่วมใช้ไม่ได้ และเมื่อเมทธอดจบการทำงานตัวแปรของเมทธอดก็หายไปด้วย ดังโปรแกรมต่อไปนี้ static void MethodWithLocals( ){ int x = 1; // Variable with initial value ulong y; string z; } ตัวแปรในเมทธอด สามารถมีค่าเริ่มต้นได้ ดังค่า x มีค่าเริ่มเป็นหนึ่ง หากเราไม่กำหนดค่าเริ่มต้น ก็จะไม่มีการเริ่มสร้างตัวแปรขึ้น (not initialized) ตัวแปรแต่ละเมทธอดสามารถมีชื่อเหมือนกันได้เพราะมีขอบเขตการใช้งานภายในเมทธอดตัวเองเท่านั้น ตัวแปรใช้ร่วมกัน ในเมทธอดจะต้องเป็นตัวแปรระดับสมาชิกของคลาส ตัวแปรภายในเมทธอดไม่สามารถใช้ร่วมกันได้ ดังตัวอย่างโปรแกรมต่อไปนี้ class CallCounter_Bad{ static void Init( ){ int nCount = 0; static void CountCalls( ){ int nCount; ++nCount; Console.WriteLine("Method called {0} time(s)", nCount); static void Main( ){ Init( ); CountCalls( ); C# Programming with Visual C# 2010 Express
C# Programming with Visual C# 2010 Express จากตัวอย่างโปรแกรมที่ผ่านมา มีการทำงานผิดพลาดสองประการคือ ตัวแปร nCount มีค่าเฉพาะที่ทำงานของเมทธอดจบ และทั้งสองเมทธอดมีชื่อตัวแปรเหมือนกันได้เพราะเป็นตัวแปรท้องถิ่นของเมทธอด และ nCount ของเมทธอด CountCalls( ) ไม่ได้มีค่าเริ่มต้นมาก่อนจึงไม่สามารถเพิ่มค่าได้ วิธีแก้ไขให้ตัวแปร nCount ให้สามารถใช้งานร่วมกันได้จะต้องประกาศเป็นตัวแปรรดับสมาชิกของคลาส ดังตัวอย่างต่อไปนี้ class CallCounter_Good{ static int nCount; static void Init( ){ nCount = 0; } static void CountCalls( ){ ++nCount; Console.Write("Method called " + nCount + " time(s)."); static void Main( ){ Init( ); CountCalls( ); ขอบเขตที่ขัดกัน เมื่อมีการประกาศตัวแปรท้องถิ่น กับตัวแปรระดับสมาชิกของคลาสที่มีชื่อเหมือนกัน แต่ทั้งสองตัวต่างเป็นตัวแปรที่ต่างกันอย่างสิ้นเชิง ทำให้จะเกิดความขัดกัน โดยที่การทำงานของโปรแกรมก็จะยังคงทำได้แต่อาจมีผลที่ผิดพลาดได้โดยที่คอมไพเลอร์ไม่ได้แจ้งเตือน ดังเช่นตัวอย่างต่อไปนี้ class ScopeDemo { static int numItems = 0; static void Method1() { int numItems = 42; static void Method2() { numItems = 61; C# Programming with Visual C# 2010 Express
การประกาศและเรียกใช้ตัวพารามิเตอร์ Parameter การประกาศตัวพารามิเตอร์ วางในวงเล็บหลังชื่อเมทธอด กำหนดชนิดข้อมูลและชื่อตัวพารามิเตอร์ การเรียกเมทธอดกับตัวพารามิเตอร์ เรียกชื่อและตามด้วยชนิดตัวพารามิเตอร์ให้ครบจำนวน ตัวอย่างการใช้ static void MethodWithParameters(int n, string y){ ... } ตัวอย่างการเรียก MethodWithParameters(2, "Hello, world“); พารามิเตอร์สามารถส่งเข้า และส่งออกเมทธอดได้ เมื่อเราต้องนิยามเมทธอด เราจะต้องรวมตัวพารามิเตอร์เข้าหรือตัวพารามิเตอร์ออกไว้ด้วย การประกาศตัวพารามิเตอร์จะต้องระบุชนิดตัวพารามิเตอร์โดยวางในวงเล็บหลังชื่อเมทธอด การประกาศตัวพารามิเตอร์ของเมทธอดคล้ายกับการประกาศตัวแปรท้องถิ่นของเมทธอด ยกเว้นประกาศตัวแปรรวมหลายตัวพร้อมกันของตัวแปรท้องถิ่น ดังตัวอย่างต่อไปนี้ Static void MethodWithParameters(int n, string y) { //…. } จากตัวอย่างนี้ตัวพารามิเตอร์เข้ามีสองตัว คือ n และ y พร้องบอกชนิดตัวพารามิเตอร์เข้า ส่วนตัวพารามิเตอร์ออกไม่มีเพราะประกาศเป็น void การเรียกใช้เมทธอดและตัวพารามิเตอร์เข้า เมื่อต้องเรียกเมทธอดจะต้องใส่ตัวพารามิเตอร์ตามที่ได้นิยามตัวพารามิเตอร์ไว้ด้วย จากตัวอย่างเมทธอด MethodWithParameters(int n, string y){//..} เมื่อต้องการเรียกใช้งานจะต้องใช้คำสั่ง MethodWithParameters(2, “Hello, World”) ซึ่งการระบุตัวพารามิเตอร์เป็นชนิดตัวเลขเป็นลำดับแรก และตัวอักษรเป็นลำดับที่สอง และครบจำนวนแล้วตามที่ได้นิยามเมทธอด C# Programming with Visual C# 2010 Express
เมทธอดโอเวอร์โหลด (overload) Overloaded Method คือเมทธอดที่มีชื่อเหมือนกับภายในคลาส มีเป้าหมายเพื่อให้ตอบสนองต่างกัน ในชื่อเมธอดเดียวกัน ตามความเหมาะสมที่จะสนับสนันการเรียกใช้งาน เช่น มี ข้อมูลตัวแปรที่ส่งเข้าเมธอด ไม่เหมือนกัน ความแตกต่างอยู่ที่รายการตัวพารามิเตอร์ของเมทธอด การเรียกใช้เมทธอด ต้องระบุรายการพารามิเตอร์ให้ตรง กับที่นิยามไว้ โอเวอร์โหลดเมทธอด คือการประกาศเมทธอดที่ชื่อเดียวกันภายในคลาสเดียวกัน การแยกความแตกต่างได้โดยพารามิเตอร์ไม่เหมือนกัน เช่น Add(int a, int b, int c) กับ Add(int a, int b) ทั้งสองตัวมีจำนวนพารามิเตอร์ไม่เท่ากัน เวลาเรียกใช้ก็ใส่ตัวพารามิเตอร์ให้ตรงกับเมทธอดที่ต้องการ เช่น Console.WriteLine(Add(1,2) + Add(1,2,3)) class OverloadingExample{ static int Add(int a, int b){ return a + b; } static int Add(int a, int b, int c){ return a + b + c; static void Main( ){ Console.WriteLine(Add(1,2) + Add(1,2,3)); เราไม่สามารถจะประกาศชื่อตัวแปร และชื่อเมทธอด เหมือนกันได้ เช่น class BadMethodNames{ static int k; static void k( ) { // ... static int Add(int a, int b){ return a + b; } static int Add(int a, int b, int c){ return a + b + c; C# Programming with Visual C# 2010 Express
ลักษณะโอเวอร์โหลดที่ทำได้ Signature Signature เป็นรายการพารามิเตอร์ของเมทธอดที่ต้องไม่มีซ้ำกัน ของการทำโอเวอร์โหลดเมทธอด ดังมีความต่างคือ ชนิดตัวแปรไม่เหมือนกัน จำนวนตัวแปรไม่เท่ากัน ลำดับตัวแปรไม่เหมือนกัน(ดูที่ชนิดตัวแปร) Signature ไม่รวมชื่อตัวพารามิเตอร์ การคืนค่าของเมทธอด แต่การคืนค่าต้องเหมือนกัน ซีชาร์ป ใช้ signature เพื่อแยกความแตกต่างระหว่างเมทธอดในคลาส ในแต่ละคลาส signature ของเมทธอดโอเวอรโหลดจะต้องมีความแตกต่างกัน ความแตกต่างกัน มีได้คือ ชนิดพารามิเตอร์ ลำดับพารามิเตอร์ที่ชนิดต่างกัน จำนวนพารามิเตอร์ ดังตัวอย่างต่อไปนี้ เป็นการประกาศที่ถูกต้อง static int LastErrorCode( ){ } static int LastErrorCode(int n){ } static int LastErrorCode(int n, int p){ } Signature ไม่รวม ชื่อของตัวพารามิเตอร์ และการคืนค่าของเมทธอด ดังตัวอย่างต่อไปนี้ ถือว่าประกาศไม่ถูกต้อง static int LastErrorCode(int n){ } static int LastErrorCode(int x){ } static string LastErrorCode(int n){ } class Customer { private int id; public void SetId(int value) { id = value; } public void SetId(string value) { if (! int.TryParse(value, out id)) Console.WriteLine("failed:Must be integer value."); } public int GetId() { return id; } C# Programming with Visual C# 2010 Express
ตัวแปรทางเลือกของเมธอด Option การทำโอเวอร์โหลดไม่เพียงพอที่สนับสนุนการทำงานแบบ นี้ void OptionalPara(int x1, float x2) { ทำงานอย่างแบบ1} void OptionalPara(int x1, int x2, float x3) { ทำงานอย่างแบบ2} void OptionalPara(int x1, float x3) // ทำไม่ได้ { ทำงานอย่างแบบ3} ซีชาร์ปสนับสนุนการใช้เป็นแปรที่ให้เลือกให้ใส่ได้ ไม่ใส่ก็ ได้ (ที่เรียกชื่อว่าทางเลือกมาจากคำว่า Option) แต่ยังคง ทำงานได้ การใช้การทำโอเวอร์โหลด ยังไม่เพียงพอ เพราะด้วยข้อจำกัด ที่ชนิดและจำนวน เหมือนกันต้องทำงานเหมือนกัน ยกตัวอย่างให้ชัดขึ้น สมมุติว่า void OptionalPara(int x1, float x2) { Console.WriteLIne( “ ชอบดอกไม้” ); } void OptionalPara( int x1, int x2, float x3) { Console.WriteLIne( “ ชอบดูหนัง” ); สองแบบนี้ แยกความชอบได้ เพราะใส่ตัวแปรเข้าไม่เท่ากัน แต่ถ้าแบบต่อไปนี้ละ void OptionalPara( int x1, float x3) { Console.WriteLIne( “ ชอบฟังเพลง” ); ใส่ตัวแปรเหมือนแบบแรกเลย แต่ไม่ได้ชอบดอกไม้ ฉันชอบฟังเพลง ทำอย่างไรดี อยากใส่ตัวแปรแบบนี้ ซีชาร์ป เสอนทางเลือกให้ ใส่ตัวแปร แบบทางเลือก C# Programming with Visual C# 2010 Express
การสร้างตัวแปรทางเลือก void OptionalPara(int x1, float x2) { ทำงานอย่างแบบ1} void OptionalPara(int x1, int x2, float x3) { ทำงานอย่างแบบ2} void OptionalPara(int x1, float x2, float x3 = 0.0F) { ทำงานอย่างแบบ3} เราสร้างตัวแปรทางเลือกที่มีการทำโอเวอร์โหลดไปด้วย เราจะ ใส่ตัวแปร 2 ตัว หรือ 3 ตัวก็ได้ และสังเกตด้วยว่า เมธอด สุดท้ายมีตัวแปรเข้า 3 ตัว มีการกำหนดค่าให้ตัวแปรสุดท้าย = 0.0F แต่ในการทำงานจริงสามารถเปลี่ยนค่าเป็น 10.0F ได้ สำหรับการไม่ใส่ตัวแปรที่ 3 เมธอดนี้จะกำหนดค่าปริยายให้ โดยสามารถใส่เงื่อนไขได้ ต้องให้ตัวแปรทางเลือกอยู่ในลำดับสุดท้ายเท่านั้น C# Programming with Visual C# 2010 Express
การเรียกเมธอดด้วยการระบุชื่อตัวแปร นอกจากการใส่ตัวแปร และชนิดตัวแปรตามลำดับของการ กำหนดเมธอดแล้ว ซีชาร์ป ยังยืดหยุ่นได้อีก ด้วยการใส่ ตัวแปร และชนิดตัวแปร ไม่ต้องตามลำดับได้ ด้วยการ กำหนดชื่อตัวแปรเข้าในการเรียกใช้งาน ดังตัวอย่าง ต่อไปนี้ static void Main(string[] args) { OptionalPara(x1: 1, x3: 10.0F, x2:2.0F); Console.ReadKey(); } static void OptionalPara(int x1, float x2, float x3 = 0.0F) Console.WriteLine("Optional3Para"); Console.WriteLine("x1:{0}", x1); Console.WriteLine("x2:{0}", x2); if (x3!=0.0) Console.WriteLine("x3:{0}", x3); นี้ก็เป็นอีกวิธี หนึ่ง ที่เป็นไปได้ว่า นักเขียนโปรแกรม จำชื่อตัวแปร ไม่จำลำดับไม่ได้ เช่น เราสร้างเมธอด สร้างคำสั่งซื้อ เราจำได้ว่า ต้องมีชิ่อลูกค้า ต้องมีรหัส ต้องมีอายุ เราใส่ชื่อตัวแปรไปเลย ซึ่งยืดหยุ่นได้มาก ถึงแม้จะมี Intellisense ช่วย แต่นี้ก็สร้างการอ่านโด้ดได้ง่ายขึ้น ในตัวอย่างในสไลด์นี้ สร้างเมธอด ชื่อ OptionalPara ที่มีตัวแปรเข้า สามตัว และมีการเรียกเมธอดนี้ใน เมธอด main การเรียกใช้เรียกแบบมีชื่อตัวแปรกำกับด้วย ซึ่งไม่จำเป็นต้องเรียงตามทิ่นิยามไว้ในตัวแปร สังเกตว่า มีการเรียกใช้เมธอดนี้ได้เลย ทำไมไม่ต้องสร้างเป็นออปเจ็กต์ก่อน? C# Programming with Visual C# 2010 Express
การสร้างเมธอดอัตโนมัติ (Refactoring Code) C# Programming with Visual C# 2010 Express
กลไกการส่งตัวแปร รูปแบบการส่งผ่านตัวแปรมีอยู่สามแบบคือ การส่งตัวแปรเข้า (By Value) การส่งแบบนี้บางทีก็เรียก in ซึ่งเป็นค่าปริยาย (ไม่ใส่คำว่า in) ตัวแปรนี้จะทำสำเนาตัวแปร เข้ามา จะมีผลเฉพาะตัวแปรภายในเมธอดเท่านั้น ส่วนใหญ่ การในการเขียนโปรแกรมจะใช้การส่งตัวแปรเข้าแบบนี้ ซึ่งที่ ผ่านมาเราก็ใช้แบบนี้ทั้งหมด การส่งตัวแปรโดยการอ้างอิง (By Reference) การส่งแบบนี้ไม่มี การทำสำเนาตัวแปรตันทางแต่จะใช้การอ้างอิงแทน ดังนี้การ เปลี่ยนแปลงตัวแปรนี้จึงมีผลต่อตัวแปรต้นทาง หรือเรียกว่า มี in และ out การส่งตัวแปรออก หรือเรียกว่า out เพราะตัวแปรนี้ มีผลต่อ ตัวแปรภายนอก แต่ไม่มีผลต่อตัวแปร ภายในเมธอด C# Programming with Visual C# 2010 Express
ตัวอย่างการใช้ตัวแปร By Value static void AddOne(int x) { x++; // Increment x } static void Main( ) int k = 6; AddOne(k); Console.WriteLine(k); // Display the value 6, not 7 C# Programming with Visual C# 2010 Express
ตัวอย่างการใช้ตัวแปรเข้าแบบอ้างอิง static void Main(string[] args){ int i = 6; int j = 6; AddRefOneValueOne(ref i, j); Console.WriteLine("{0}, {1}", i,j); // Display the value 7, 6 Console.ReadKey(); } static void AddRefOneValueOne(ref int x, int y){ x++; y++; C# Programming with Visual C# 2010 Express
ตัวอย่างการใช้ตัวแปร out static void OutMethod(out int p){ p = 1; } static void Main(string[] args){ int p = 2; OutMethod(out p); Console.WriteLine(p);// Display 1 Console.Read(); C# Programming with Visual C# 2010 Express
การใช้ตัวแปรเข้าแบบไดนามิกด้วยอะเรย์ ในบางครั้งเมื่อต้องการให้ตัวแปรเข้า หลายตัว การใช้ เมธอดโอเวอร์โหลด จำนวนที่มีตัวเข้าต่างๆ จะทำให้มี เมธอดโอเวอร์โหลดจำนวนมาก เกินไป การแก้ปัญหานี้แก้ได้ด้วยการทำ ให้มีตัวแปรเข้าแบบได นามิก ใช้คีย์เวิร์ด params ประกาศเป็นอาร์เรย์ ส่งผ่านบบ การส่งตัวพารามิเตอร์เข้า static long AddList(params long[ ] v){ long total, i; for (i = 0, total = 0; i < v.Length; i++) total += v[i]; return total; } static void Main( ){ long x = AddList(63,21,84); การประกาศจำนวนตัวแปรที่พารามิเตอร์ได้ ในบางครั้งต้องการใช้เมทธอดสามารถรับจำนวนตัวพารามิเตอร์ที่แปรผันได้ ในซีชาร์ป ใช้คีย์เวิร์ดว่า params เพื่อระบุว่าเป็นตัวแปรที่มีจำนวนไม่คงที่ และมีกฏดังนี้ มีเพียงหนึ่ง params ต่อหนึ่งเมทธอด วางได้ที่ตำแหน่งท้ายสุดของตัวแปร มีเพียงหนึ่งมิติของอเรย์เท่านั้น ตัวอย่างต่อไปนี้แสดงการประกาศตัวแปรที่แปรผันได้ static long AddList(params long[ ] v){ long total; long i; for (i = 0, total = 0; i < v. Length; i++) total += v[i]; return total; } เพราะ params เป็นอเรย์จึงต้องมีตัวแปรเป็นชนิดข้อมูลเดียวกัน C# Programming with Visual C# 2010 Express
การส่งผ่านตัวพารามิเตอร์ เมื่อคุณต้องการเรียกใช้เมทธอดที่มีตัวพารามิเตอร์ไม่คงที่นี้ การส่งตัวแปรจะส่งแบบตัวพารามิเตอร์เข้า (pass by value) ได้สองวิธี คือ ใช้จุลภาค (, ) คั่นระหว่างตัวแปร ใช้ในลักษณะอเรย์ ตัวอย่างต่อไปนี้แสดงลักษณะการส่งตัวพารามิเตอร์เข้า ทั้งสองลักษณะ static void Main( ){ long x; x = AddList(63, 21, 84); // List x = AddList(new long[ ]{ 63, 21, 84 }); // Array } ไม่ว่าจะเรียกใช้เมทธอดได้วิธีใด params เป็นลักษณะอเรย์ สามารถใช้คุณสมบัติ Length เพื่อดูขนาดของอเรย์ได้ เนื่องจากเป็นส่งตัวแปรเข้า ในลักษณะการทำสำเนาตัวแปรเข้าไป การเปลี่ยนค่าของตัวแปรจะไม่มีผลต่อ ตัวแปรนอกที่ส่งเข้าไป C# Programming with Visual C# 2010 Express
เงื่อนไขการใช้ตัวแปรเข้าแบบไดนามิก มีเพียงหนึ่ง params ต่อหนึ่งเมธอด วางได้ที่ตำแหน่งท้ายสุดของตัวแปร มีเพียงอะเรย์หนึ่งมิติเท่านั้น static void Main(string[] args) { Console.WriteLine(Accumulate("total:", 1, 2, 3, 4)); //print total:10 Console.ReadKey(); } public static string Accumulate(string print, params int[] value ) { int sum = 0; foreach (var item in value) { sum += item; } return print + Convert.ToString(sum); C# Programming with Visual C# 2010 Express
แนวทางการใช้ตัวพารามิเตอร์ของเมทธอด กลไกการทำงาน Pass by value เป็นวิธีที่นิยมใช้กันมากที่สุด เมทธอดที่คืนค่า จะมีประโยชน์กับการส่งออกเพียงตัวเดียว การใช้ ref และ out นิยมใช้กับการคืนค่าหลายค่า ใช้เพียง ref ถ้าข้อมูลมีการส่งค่าทั้งสองทาง ประสิทธิภาพ โดยทั่วไปประสิทธิภาพของ pass by value มีมากที่สุด ด้วยทางเลือกที่มีให้มากในการส่งตัวพารามิเตอร์ของเมทธอด มีปัจจัยสองประการในการเลือกใช้คือ กลไกการทำงาน Pass by value เป็นวิธีที่นิยมใช้มากที่สุด เพราะการเปลี่ยนแปลงใดเกิดขึ้นภายในเมทธอดเท่านั้น หากว่าต้องการจะส่งตัวแปรออกออกนอกเมทธอด มีอยู่สองวิธีคือการใช้ return และ ref เป็นคีย์เวิร์ด ต่างกันที่ return จะใช้กับการส่งตัวแปรออกเพียงตัวเดียง แต่ ref ส่งตัวแปรออกได้หลายตัวได้ และมีการเปลี่ยนแปลงเกิดขึ้นสองทาง ในกรณีที่ต้องการเกิดการเปลี่ยนเฉพาะทางออกเท่านั้นก็ให้ใช้ out คีย์เวิร์ดกับตัวแปรเมทธอด ประสิทธิภาพการทำงาน ชนิดตัวแปรที่ทำงานได้เร็วคือ int, long มีประสิทธิภาพที่สุด และต้องใช้กับ pass by value C# Programming with Visual C# 2010 Express
การใช้เมทธอดเรียกตัวเอง (Recursive) Method เมทธอดที่เรียกตัวเอง โดยตรง โดยอ้อม มีประโยชน์กับโครงสร้างปัญหาที่ซับซ้อน เมทธอดที่เรียกตัวเอง เป็นเทคนิคที่เรียกกันว่า recursion การใช้แก้ปัญหามักใช้กับโครงสร้างข้อมูลปัญหาที่ซับซ้อน เช่น list และ tree เมทธอดใน C# สามารถเรียกกันเองได้ เช่น เมทธอด A สามารถเรียกเมทธอด B และเมทธอด B สามารถเรียกเมทธอด A ได้ ตัวอย่างเมทธอดรีเคอร์ซีพ เลขชุดไฟโบนาชชี่ (Fibonacci) เกิดขึ้นได้กับทางคณิตศาสตร์และชีววิทยา เช่น การเกิดของประชากรของกระต่าย ชุดลำดับเลขที่ n มีการบวกเป็นลำดับของสองลำดับก่อนหน้า คือ (n-1) + (n-2) ยกเว้นลำดับที่ 1 และ 2 มีค่าเท่ากับ 1 เมื่อกำหนดให้เมทธอดเรียกเมทธอดตัวเอง ของการบวกเลข Finbonacci นี้จะเขียนได้ดังนี้ static ulong Fibonacci(ulong n){ if (n <= 2) return 1; else return Fibonacci(n-1) + Fibonacci(n-2); } static void Main(string[] args) { for (ulong i = 0; i < 10; i++) { Console.WriteLine(i + ":" + Fibonacci(i)); Console.Read(); การทำงานแบบรีเคอร์ซีพจะมีจุดที่โปรแกรมหยุดได้เสมอ หากไม่มีแล้วโปรแกรมจะทำงานม่รู้จบ ในตัวอย่างโปรแกรมนี้ คือ n <= 2 เป็นจุดที่ช่วยหยุดโปรแกรม static ulong Fibonacci(ulong n){ if (n <= 2) return 1; else return Fibonacci(n-1) + Fibonacci(n-2); } C# Programming with Visual C# 2010 Express
สรุปท้ายบท บทนี้เราได้เรียนรู้การสร้างเมธอด การใช้งานเมธอด การทำโอเวอร์โหลด กฎเกณฑ์ การสร้างเมธอดในลักษณะ ต่างๆ โดยเฉพาะเรื่อง การสร้างตัวแปรเข้า หรือ พารามิเตอร์ในลักษณะ ไดนามิกของอะเรย์ ไดนามิกของ ทางเลือก การระบุชื่อตัวแปร ในกรณีที่ไม่เรียงลำดับตัวแปร เข้า กลไกการทำงานของตัวแปรเข้า แบบทำสำเนาเข้า แบบอ้างอิงตัแปรเข้า และแบบอ้างอิงภายนอกอย่างเดียว รวมทั้งเมธอดเรียกตัวเองสำหรับโครงสร้างปัญหาที่ซับซ้อน C# Programming with Visual C# 2010 Express
คำถามทบทวน เมธอดอาจเรียกได้หลายชื่อ ชื่อเหล่านั้นคืออะไรได้บ้าง มีเหตุผลอะไรที่ต้องสร้างสเตติกเมธอด และอินสแตทซ์เมธอด มีเหตุผลอะไรที่จะต้องทำโอเวอร์โหลดเมธอด ให้เขียนรายการลักษณะตัวแปรเข้าที่ทำโอเวอร์โหลดได้บ้าง ใช้คีย์เวิร์ดอะไรในการสร้างตัวแปรเข้าแบบไดนามิก ด้วยอะเรย์ มีเหตุผลอะไรที่ซีชาร์ปต้องสร้างตัวแปรทางเลือก ในกรณีที่ใช้การะบุชื่อตัวแปรเข้าทุกตัว ยกเว้นตัวแปร ทางเลือก ในการเรียกใช้งานเมธอดที่ตัวแปรทางเลือก ค่าตัวแปรทางเลือกจะมีค่าเป็นอะไร มีขั้นตอนอะไรบ้างในการสร้างเมธอดอัตโนมัติ C# Programming with Visual C# 2010 Express
คำถามทบทวน จากโค้ดต่อไปนี้ เมื่อเรียกเมธอด OutMethod( ) จะเกิดอะไร ขึ้น static void OutMethod(out int p){ p = 1;} static void Main(string[] args){ int p; OutMethod(out 1); Console.WriteLine(p); Console.Read(); } ชนิดตัวแปรเข้ามีกี่ชนิด จำแนกตามกลไกการส่งตัวแปร ประสิทธิภาพในการใช้ตัวแปรโดยทั่วไป ใช้ชนิดข้อมูลของ ตัวแปรเข้าเป็นอะไรจะดีที่สุด เมธอดเรียกตัวเอง หรือรีเคอร์ซีพ จำเป็นต้องมีการจุดหยุด ของการทำงานหรือไม่ และเพราะอะไร C# Programming with Visual C# 2010 Express
Lab การสร้างและใช้งานเมทธอด Lab 6 Method การใช้พารามิเตอร์ในเมทธอดที่ส่งค่าคือ การสร้างเมทธอดกับพารามิเตอร์อ้างอิง การใช้เมทธอด รีเคอร์ชั่น จากคลาส Utils ต่อไปนี้ class Utils{ // Return the greater of two integer values // public static void Main( ){ // Test } ให้เพิ่มเมทธอดชื่อ Greater ( ) ที่มีพารามิเตอร์สองตัว ชื่อ a และ b ทั้งสองมีชนิดข้อมูลเป็น int และเมทธอดนี้คืนค่า (return) เป็น int โดยมีเงื่อนการคืนค่าว่า ถ้า a > b จะคืนค่า a แต่ถ้า b >= a แล้วจะคืนค่า b (หมายเหตุ เมทธอดนี้มี public static นำหน้าชื่อเมทธอด ) ทดสอบ การใช้การเมทธอดใน public static void Main( ) ภายในคลาสนี้ มีการส่งคืนค่า ดังนี้ int x; int y; int greater; x = int.Parse( Console.ReadLine( )); y = int.Parse( Console.ReadLine()); greater = greater(x, y); Console.WriteLine(“ The greater value is “ + greater); Console.ReadLine( ); เก็บภาพหน้าจอแล้วส่งมาทางอีเมล์ C# Programming with Visual C# 2010 Express
2. เมทธอดกับตัวพารามิเตอร์อ้างอิง ให้สร้างเมทธอดที่ชื่อ public static void Swap ( ) ที่มีพารามิเตอร์สองตัว มีชนิดข้อมูลเป็น int ชื่อ a และ b เมทธอดนี้ใช้สำหรับการสลับค่าตัวแปร ให้ a มีค่าเป็น b และ b มีค่าเป็น a การส่งตัวพารามิเตอร์ให้เป็น ref class Utils{ // Exchange two integers, passed by reference // public static void Main( ){ // Test } ทดสอบการใช้งานเมทธอด Swap ( 4, 5 ) แล้วส่งภาพหน้าจอส่งทางอีเมล์ 3. การใช้เมทธอดรีเคอร์ซีพ ( recursive method ) ให้สร้างเมทธอดรีเคอร์ซีพ ให้ทำหน้าที่คือ ค่า factorial ที่สามารถทำงานได้ดังหน้าจอต่อไปนี้ แล้วส่งโค้ทเมทธอดนี้ทางอีเมล์ Factorial(0) = 1 Factorial(1) = 1 Factorial(2) = 2 Factorial(3) = 6 Factorial(4) = 24 C# Programming with Visual C# 2010 Express