ตอน 22 method parameter

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


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

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

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

 

method parameter

ภาษา C# ก็เช่นเดียวกับภาษาอื่นๆ ที่เมื่อเรานิยาม method เราสามารถกำหนดให้มีพารามิเตอร์หรือไม่ก็ได้ พารามิเตอร์คือการส่งค่าให้ method พารามิเตอร์ในภาษา C# มี syntax ดังนี้

[modifier] data type ชื่อพารามิเตอร์

    • modifier ทำหน้าที่กำหนดวิธีส่ง (ดูย่อหน้าต่อไป)
    • data type คือลักษณะของข้อมูล เช่น int, byte, bool
    • ชื่อพารามิเตอร์ เป็นชื่อที่เราตั้งให้แก่พารามิเตอร์ เช่น salary, studentName

พารามิเตอร์ในภาษา C# มีสี่แบบคือ
    1. value parameter: ไม่ต้องใส่ modifier
    2. ref parameter: ใส่ modifier ref
    3. out parameter: ใส่ modifier out
    4. params parameter: ใส่ modifier params

Value parameter: บางคนเรียก in parameter เป็นวิธีปรกติธรรมดา หากท่านไม่ระบุ CLR จะถือว่าเป็นการส่งพารามิเตอร์แบบนี้โดยปริยาย การส่งแบบนี้ CLR จะสร้างตัวแปรขึ้นใหม่ภายใน method ที่รับพารามิเตอร์ และจะกำหนดค่าเริ่มต้นของมันเป็นข้อมูลที่ท่านส่งไป หากท่านเปลี่ยนแปลงตัวแปรนี้ ข้อมูลดั้งเดิมของท่านจะไม่ได้รับผลกระทบ โปรดดูตัวอย่างโค้ดต่อไปนี้

1     using System;
2
3     namespace ConsoleApplication1
4     {
5         class Program
6         {
7             static void Main(string[] args)
8             {
9                 int i = 2, j = 3;
10                Console.WriteLine(Add(i, j));
11                Console.WriteLine(i);
12                Console.WriteLine(j);
13                Console.ReadLine();
14            }
15            static int Add(int i, int j)
16            {
17                i++;
18                j++;
19                return i + j;
20            }
21        }
22     } 

บรรทัดที่ 9 มีการสร้างตัวแปรชื่อ i และ j จากนั้นส่งค่าของ i และ j ไปเป็นพารามิเตอร์ให้แก่ method Add ในบรรทัดที่ 10 โดยไม่ระบุ modifier ซึ่งจะทำให้เป็น value parameter ไปโดยปริยาย จากนั้นภายใน method Add บรรทัดที่ 17,18 มีการเปลี่ยนแปลงค่า i และ j แต่ตัวแปร i และ j ที่อยู่ภายใน method Main จะไม่ได้รับผลกระทบ (ไม่เปลี่ยนแปลง) ผลลัพธ์ของโปรแกรมนี้คือ

7
2
3

ref parameter: การส่งพารามิเตอร์แบบนี้ไม่ได้ส่งค่าของตัวแปร แต่เป็นการส่งตัวแปรไปจริงๆ จึงไม่มีการสร้างตัวแปรใหม่ แต่จะใช้ตัวแปรนั้นๆ โดยตรง เมื่อเราเปลี่ยนแปลงค่าของตัวแปรภายใน method ที่รับพารามิเตอร์ ค่าของตัวแปรใน method ที่ส่งพารามิเตอร์จะเปลี่ยนไปด้วย โปรดดูตัวอย่างต่อไปนี้

1     using System;
2 
3     namespace ConsoleApplication1
4     {
5         class Program
6         {
7             static void Main(string[] args)
8             {
9                  int i = 2, j = 3;
10                 Console.WriteLine(Add(ref i, ref j));
11                 Console.WriteLine(i);
12                 Console.WriteLine(j);
13                 Console.ReadLine();
14            }
15            static int Add(ref int i, ref int j)
16            {
17                i++;
18                j++;
19                return i + j;
20            }
21        }
22     } 

เมื่อรันโปรแกรมนี้ค่าที่ได้จะเป็น

7
3
4

โปรดสังเกตด้วยว่า modifier ref จะต้องใส่ไว้ทั้งที่โค้ดซึ่งเป็นตัวส่งพารามิเตอร์ (บรรทัดที่ 10) และโค้ดส่วนที่รับพารามิเตอร์ (บรรทัดที่ 15)

out parameter: การส่งพารามิเตอร์แบบนี้คล้ายๆ ref ในแง่ที่เป็นการส่งตัวแปรไปจริงๆ จึงไม่มีการสร้างตัวแปรใหม่ แต่จะแตกต่างจากการส่งแบบ ref ตรงที่ตัวแปรที่ถูกส่งไปไม่จำเป็นต้องถูกกำหนดค่าไว้ก่อนก็ได้ โปรดดูโค้ดต่อไปนี้

1     using System;
2
3     namespace ConsoleApplication1
4     {
5         class Program
6         {
7             static void Main(string[] args)
8             {
9                  int i, j;
10                 Console.WriteLine(Add(out i, out j));
11                 Console.WriteLine(i);
12                 Console.WriteLine(j);
13                 Console.ReadLine();
14             }
15             static int Add(out int i, out int j)
16             {
17                 i=2;
18                 j=3;
19                 return i + j;
20             }
21         }
22     } 

โปรดสังเกตว่าเราสร้างตัวแปร i และ j ไว้ใน method Main ในบรรทัดที่ 9 โดยไม่ได้กำหนดค่าให้มัน แล้วเราส่งมันไปเป็นพารามิเตอร์ทันทีในบรรทัดที่ 10 เมื่อรันโปรแกรมนี้ค่าที่ได้จะเป็น

5
2
3

เช่นเดียวกับ modifier ref modifier out จะต้องถูกใส่ไว้ทั้งที่โค้ดซึ่งเป็นตัวส่งพารามิเตอร์ (บรรทัดที่ 10) และโค้ดส่วนที่รับพารามิเตอร์ (บรรทัดที่ 15)

params parameter: ใช้สำหรับการส่ง array หรือชุดของข้อมูลไปเป็นพารามิเตอร์ จึงเรียกอีกชื่อหนึ่งว่า parameter array (PA) PA เป็นสิ่งที่มีประโยชน์มากเพราะช่วยให้เราสามารถส่งข้อมูลเป็นชุดให้แก่ method ได้โดยไม่ต้องเขียนรายการพารามิเตอร์ (parameter list) ยืดยาว โปรดดูตัวอย่างโค้ดต่อไปนี้

1     using System;
2 
3     namespace ConsoleApplication1
4     {
5         class Program
6         {
7             static void Main(string[] args)
8             {
9                  int[] x = { 1, 2, 3 };
10                 ShowNumbers(x);
11                 ShowNumbers(4, 5);
12                 Console.ReadLine();
13            }
14            static void ShowNumbers(params int[] numbers)
15            {
16                 foreach (int x in numbers)
17                 {
18                      Console.Write(x + " ");
19                 }
20                 Console.WriteLine();
21            }
22        }
23    } 

โค้ดใน method Main สร้าง array (บรรทัดที่ 9) และส่งไปเป็นพารามิเตอร์ให้กับ method ShowNumbers ในบรรทัดที่ 10 และ 11 เมื่อรันโปรแกรมนี้ผลลัพธ์ที่จะเป็น

1 2 3
4 5

โปรดสังเกตว่าการใส่ modifier params ให้ใส่เฉพาะที่ method ที่เป็นตัวรับพารามิเตอร์เท่านั้น (ตัวที่ส่งไม่ต้องใส่ keyword ใดๆ) ในกรณีที่ใช้ PA ร่วมกับพารามิเตอร์อื่นๆ PA จะต้องเป็นตัวสุดท้าย (ตัวขวาสุด) เสมอ และ PA ต้องเป็น array มิติเดียวเท่านั้น

ภาษา C# ใช้ PA เป็นเรื่องปรกติ แม้แต่ method Main ก็ใช้ PA ไลบรารี .NET มีการใช้ PA อยู่ทั่วไป ยกตัวอย่างเช่น method Console.WriteLine() ก็ใช้ PA ทำให้เราเขียนโค้ดแบบนี้ได้

Console.WriteLine(“x={0} y ={1} z={2}”, x, y, z);

จะเห็นว่าการเรียกใช้ method WriteLine() เราสามารถใส่ argument กี่ตัวก็ได้ตามใจชอบ

 

พารามิเตอร์กับ argument

คำว่าพารามิเตอร์มักถูกใช้ปะปนกันคำว่า argument (อาร์กิวเมนท์) เพราะมีความหมายคล้ายๆ กัน พารามิเตอร์หมายถึงรายการตัวแปรไว้รับค่า ที่เรานิยามไว้ในวงเล็บหลังชื่อของ method ส่วน argument หมายถึงรายการค่า หรือตัวแปรที่เราส่งให้กับ method เมื่อเรียกใช้ method

ยกตัวอย่างเช่นในโค้ดข้างบน บรรทัดที่ 14 สิ่งที่อยู่ภายในวงเล็บคือพารามิเตอร์ ส่วนบรรทัดที่ 10 สิ่งที่อยู่ภายในวงเล็บคือ argument ในกรณีที่ส่งค่าเป็น argument มากกว่าหนึ่งค่า ยกตัวอย่างบรรทัดที่ 11 จะเรียกว่า argument list

 

เดนนิส ริชชี มีคุณูปการแก่วงการคอมพิวเตอร์ เพราะเป็นผู้คิดประดิษฐ์ภาษา ซี อันเป็นภาษาที่มีอิทธิผลต่อภาษาในยุคต่อมา อาธิ ภาษา C++, JavaScript, Java และ C#

 

method signature

method signature คือรายการพารามิเตอร์ของ method รายการพารามิเตอร์คือค่าต่างๆ ที่เราส่งให้กับ method ลองพิจารณาเมธอดนี้


1 public int AddNumber(int x, int y)
2 {
3     answer = x + y;
4     return answer;
5 } 

ในตัวอย่างนี้ AddNumber เป็น method ที่มี return type เป็นแบบ int และต้องการรับพารามิเตอร์สองตัวที่เป็น int ทั้งคู่ คือ x และ y ในกรณีนี้ x และ y คือรายการพารามิเตอร์

ลำดับ จำนวน และ type ของพารามิเตอร์ที่เราส่งให้เมธอดจะต้องตรงกับพารามิเตอร์ list ที่นิยามไว้ตรงหัว method มิฉะนั้นจะคอมไพล์ไม่ผ่าน

รูปแบบของพารามิเตอร์ list คือ signature ลองดูตัวอย่างต่อไปนี้

1. public void fooBar(int a, int b) 
2. int int fooBar(int foo, int bar) 
3. public void fooBar(int a, double b) 
4. internal int fooBar(int a, int b, int c) 

การจะพิจารณาว่า method สอง method มี signature ตรงกันหรือไม่ให้ดูที่พารามิเตอร์ ในกรณีตัวอย่างข้างบน method ที่ 1 และ 2 ถือว่าซ้ำกัน เพราะพารามิเตอร์เหมือนกันทุกประการ

signature ของ method ประกอบด้วยสิ่งต่างๆ ดังนี้
• ชื่อ method
• จำนวนพารามิเตอร์
• type ของพารามิเตอร์
• ชนิดของพารามิเตอร์ (คือ value, reference หรือ output)
• ลำดับของพารามิเตอร์ (เรียงจากซ้ายไปขวา)

signature ของ method ไม่รวมสิ่งต่างๆ ต่อไปนี้
• return type
• ชื่อของพารามิเตอร์
• modifier params (ซึ่งจะอยู่ที่ตำแหน่งขวาสุดในรายการของพารามิเตอร์)

เรื่องของ method signature มีความสำคัญเมื่อท่านต้องการทำ method overloading

 

method overloading

ในภาษา C# เราสามารถนิยาม method ชื่อเดียวกันหลายๆ แบบไว้ภายในคลาสเดียวกันได้ โดยมีข้อแม้ว่า signature ต้องไม่เหมือนกัน ความสามารถเช่นนี้ของภาษา C# มีประโยชน์มาก เพราะช่วยให้การใช้งาน type สะดวกขึ้น ภาษา C# ไม่เพียงสนับสนุนให้เราทำ method overloading (ต่อไปจะเรียกย่อว่า MO) เท่านั้น แต่ตัว .NET Framework เอง ยังใช้ MO อย่างกว้างขวางอีกด้วย ลองดูโค้ดตัวอย่างต่อไปนี้

1     using System;
2
3     namespace ConsoleApplication1
4     {
5        class Program
6        {
7           static void Main(string[] args)
8           {
9              Console.WriteLine(1);
10             Console.WriteLine("hello");
11             Console.WriteLine('c');
12             Console.WriteLine(123.456);
13          }
14       }
15    } 

ผู้เขียนเรียกใช้ method WriteLine() ซึ่งเป็น method ที่อยู่ในคลาส Console ของ namespace System ในบรรทัดที่ 9 ผู้เขียนเรียกใช้ method WriteLine() โดยส่งพารามิเตอร์ไปเป็นเลขจำนวนเต็ม ในบรรทัดที่ 10 ผู้เขียนเรียกใช้ method WriteLine() โดยส่งพารามิเตอร์ไปเป็น string ในบรรทัดที่ 11 ผู้เขียนเรียกใช้ method WriteLine() โดยส่งพารามิเตอร์ไปเป็น char ในบรรทัดที่ 12 ผู้เขียนเรียกใช้ method WriteLine() โดยส่งพารามิเตอร์ไปเป็นเลขแบบมีจุดทศนิยม เมื่อรันโปรแกรมนี้ ผลลัพธ์ที่ได้คือ

1
hello
c
123.456

ท่านสงสัยหรือไม่ว่า เพราะอะไรการเรียกใช้ method WriteLine()ในตัวอย่างข้างบนจึงไม่เกิด error ทั้งๆ ที่การส่งพารามิเตอร์แต่ละครั้งไม่เหมือนกันเลย คำตอบคือผู้สร้าง method WriteLine() ได้สร้าง method WriteLine() ไว้ในรูปแบบต่างๆ กันถึง 18 แบบ หรือพูดอีกอย่างหนึ่งคือทำ MO ไว้ 18 รูปแบบนั่นเอง ท่านคงเห็นแล้วว่าการทำ MO ช่วยให้การใช้งาน type สะดวกขึ้นมาก

ต่อไปนี้ผู้เขียนจะสาทิตวิธีเขียนโปรแกรมภาษา C# เพื่อสร้างและใช้ประโยชน์จาก MO ว่าทำได้ง่ายเพียงใด โปรดพิจารณาโค้ดตัวอย่างต่อไปนี้

using System; 

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Add(1));
            Console.WriteLine(Add(1, 2));
            Console.WriteLine(Add(1, 2, 3));
            Console.ReadLine();
        }
        static int Add(int i)
        {
            return i;
        } 
        static int Add(int i, int j)
        {
            return i + j;
        }
        static int Add(int i, int j, int k)
        {
            return i + j + k;
        }
    }
} 

จะเห็นว่าผู้เขียนนิยาม method สมาชิกชื่อ Add ขึ้นโดยทำ MO ไว้สามแบบ แบบแรกรับพารามิเตอร์ตัวเดียว แบบที่สองรับสองตัว และแบบที่สามรับสามตัว โปรแกรมที่เรียกใช้งาน method นี้สามารถเรียกใช้งาน method ได้โดยส่งพารามิเตอร์ตั้งแต่ 1 ถึง 3 ตัว เมื่อรันโปรแกรมนี้จะได้ผลลัพธ์ดังนี้

1
3
6

จะเห็นว่า method Add ทั้งสามแบบมี return type ตรงกันหมด (คือเป็น int) ในตัวอย่างนี้ชัดเจนว่า return type ควรเป็น int การทำ MO โดยให้ทุก method มี return type แบบเดียวกันหมดเป็นธรรมเนียมปฏิบัติตามปรกติ แต่ในบางกรณีเราอาจนิยามให้แต่ละ method มี return type แตกต่างกันก็ได้ ซึ่งควรทำด้วยความระมัดระวัง เพื่อหลีกเลียงปัญหาความไม่ลงรอยกันในการใช้งาน

 

การคอมไพล์

การคอมไพล์ (compile) คือการรวบรวม source code ทั้งหมดมาแปลงให้เป็นไฟล์ๆ เดียว โดยใช้โปรแกรมพิเศษที่เรียกว่า compiler เมื่อคอมไพล์แล้วผลลัพธ์ที่ได้จะเป็นไฟล์ assembly ซึ่งอาจเป็นไฟล์นามสกุล .exe หรือ .dll ก็ได้ ยกตัวอย่างเช่นโปแกรมต่อไปนี้

using System; 

namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World");
        }
    }
} 

หากเราเก็บเป็น source code ชื่อ hello.cs เราสามารถคอมไพล์ได้โดยพิมพ์คำสั่งต่อไปนี้ที่ command prompt

csc hello.cs

ผลลัพธ์ที่ได้คือไฟล์ชื่อ hello.exe ไฟล์นี้เป็นโปรแกรมประยุกต์ที่เราสามารถนำไปรันในคอมพิวเตอร์เครื่องไหนก็ได้ที่ติดตั้ง .NET Framework ไว้

สมมุติว่าเราสร้างโปรแกรมไว้เพื่อต้องการใช้เป็น class library ดังนี้

using System; 

namespace CSharpBook
{
    class MyLib
    {
        public static string DecToHex(int dec)
        {
            uint uiDecimal = 0;
            uiDecimal = checked((uint)System.Convert.ToUInt32(dec.ToString()));
            return String.Format("{0:x2}", uiDecimal);
        }
    }
} 

หากเราเก็บเป็น source code ชื่อ csharpbook.cs เราสามารถคอมไพล์ให้เป็นไลบรารีได้โดยพิมพ์คำสั่งต่อไปนี้ที่ command prompt

csc /t:library csharpbook.cs

ผลลัพธ์ที่ได้คือไฟล์ชื่อ csharpbook.dll ไฟล์นี้เป็น class library ที่เราสามารถนำไปใช้งานร่วมกับ project อื่นที่เขียนด้วยภาษา C# หรือภาษา .NET อื่นๆ ได้ทุกภาษา

ตอนต่อไป: ตัวแปร – pointer – unsafe code

Post a comment or leave a trackback: Trackback URL.

ความเห็น

ใส่ความเห็น

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: