Method with Variable-length Argument Lists

posted on 18 Jul 2005 19:00 by tidno1 in csharp-and-dotnet

Variable-length Argument Lists(C#)

ลองมาดู method ที่ใช้กันจนคุ้นเคย อย่าง WriteLine

Console.WriteLine("center is ({0},{1})", x, y);

หากลองสังเกตดู จะสังเกตได้ว่า method นี้มี parameter หลายตัว(ดูได้จากจำนวน comma(',') และก็มีขนาดไม่แน่นอนด้วย
โดยทั่วไปแล้วการ define method นั้นจะต้องกำหนด parameter ให้แน่นอน ทั้งชนิดและจำนวน

หรือถ้าเราจะสร้าง method WriteLine ให้รับ parameter เป็น array

public static void WriteLine(string format, object[] arg) {
    //...
}

การใช้งานก็คงลำบากใช่เล่น เวลาจะส่ง parameter ไปแต่ละครั้งก็ต้องมาสร้าง array ใหม่ทุก ๆ ครั้ง ส่งไปให้

Console.WriteLine("center is ({0},{1})", new object[]{x, y});

จริง ๆ ข้างบนสามารถเขียนเป็น Console.WriteLine("center is ({0},{1})", {x, y}); ก็ได้นะครับ (ใน .NET การ initialize new array ไม่จำเป็นต้องใส่ new <type>[] ไว้ข้างหน้าก็ได้ครับ)

มันก็คงดูลำบากใช่เล่นนะครับ กับการใช้ method ตัวนึง แล้วต้องมาส่ง array ให้เนี่ย คงไม่สวยงามนักหรอก ดังนั้นใน .NET จึงมีความสามารถในการ define method ให้สามารถรับ parameter โดยไม่จำกัดได้ โดยการเติม keyword params ไว้หน้า type ของ parameter ตัวนั้น

แล้วการใช้งานก็สามารถใช้ได้ ทั้งแบบการส่ง array เข้าไปแบบตัวอย่างข้างบน หรือจะใช้เป็น การส่ง argument ไปทีละตัวแบบการใช้งานปกติก็ได้
โดยการใช้งาน parameter เหล่านั้น ก็ทำได้โดยการ access array แบบปกติ

public static void WriteLine(string format, params object[] args) {
    for(int i = 0; i < args.Length; i++) {
        //...
    }
}

แถมให้อีกหน่อยละกัน ใน java(5.0) และ C ก็สามารถใช้งานได้นะครับ เอาทีละภาษาละกัน

Variable-length Argument Lists(C language)

ในภาษา C นั้น การ declare function ทำได้โดยการ include header file stdarg.h และเขียน ... ไว้เป็น parameter ตัวหลังสุด

#include <stdarg.h>

int printf(char *fmt, ...);

แต่ว่าการใช้งานนั้นไม่ได้ง่ายอย่างที่คิด โดยจะต้องนำ parameter ทั้งหมดใส่ไปใน object ที่มี type เป็น va_list โดยการส่ง parameter ตัวสุดท้ายก่อน variable argument list ไปให้กับ macro va_start โดยการใช้งาน ทำได้โดยเรียก macro va_arg ซี่งจะให้ค่า มาเป็น type ที่เราระบุลงไป และเมื่อใช้งานเสร็จแล้ว ต้องเคลียร์ทิ้งด้วย macro va_end

#include <stdarg.h>

int printf(char *fmt, ...) {
    va_list ap;
    int ival;
    double dval;
    char c, *p, *sval;

    va_start(ap, fmt);
    for(p = fmt; *p; p++) {
        if(*p != '%') {
            putchar(*p);
            continue;
        }

        switch(*++p) {
            case 'd' :
                ival = va_arg(ap, int);
                //...
                break;
            case 'f' :
                dval = va_arg(ap, double);
                //...
                break;
            case 's' :
                ival = va_arg(ap, char *);
                //...
                break;
            case 'c' :
                ival = (char)va_arg(ap, int);
                //...
                break;
            //...
            default :
                //...
                break;
        }
    }
    va_end(ap);
}

Variable-length Argument Lists(Java 5.0)

java นั้นถือว่าเป็นภาษาหลังสุดที่รองรับ feature นี้ (ออกมาใน version 1.5 หรือ Java 5.0 ซึ่งถือว่าหลังจาก .NET ออกได้หลายปีพอควร) โดยมีชื่อเรียกว่า varargs(JSR 201)ซึ่งก็ทำให้ใน Java 5.0 นั้นมี method printf ให้ใช้งาน

โดยการใช้งาน feature นี้ง่ายดายดังเช่นใน .NET แต่ว่ามี syntax คล้าย ๆ กับ C

public PrintStream printf(Locale l, String format, Object... args) {
    for(int i = 0; i < args.length(); i++) {
        //...
    }
}

แถมหน่อยละกัน สำหรับ printf ใน Java นั้น ยังมี %n ซึ่งเป็นการขึ้นบรรทัดใหม่ (การใช้ \n ทำให้ไม่ portable เนื่องจาก อักขระขึ้นบรรทัดใหม่ของ windows เป็น \r\n : carriage return ตามด้วย new line ซึ่งสลับกับเครื่องพิมพ์ดีด, ใน unix เป็น \n ตัวเดียว ที่สำคัญคือใน Mac กลับใช้ \r อย่างเดียว ซึ่งการใช้ printf("\n"); จะไม่สามารถ ขึ้นบรรทัดใหม่ได้)

สรุป
การสร้าง method ที่รองรับ variable-length argument list นั้น สร้างความสะดวกในการใช้ method นั้น แต่ไม่บ่อยครั้งนักที่เราจะได้ใช้ parameter หลายตัวนัก ดังนั้นการใช้งาน method แบบนี้อาจจะกินแรงไปบ้าง(เพราะต้องวนลูป เพื่อ access array) เราสามารถใช้การ overload method ซึ่ง specified parameter ไว้แน่นอน ดังเช่นตัวอย่างการ implement WriteLine ใน .NET ซึ่งมี overload ไว้ถึง 19 แบบ

Comment

Comment:

Tweet

Of the panoply of website I've pored over this has the most <a href="http://duuhrbfdwgk.com">vetrciay.</a>

#9 By fcn9ojyTMM (63.128.150.14) on 2013-07-30 06:33

I guess finding useful, reliable inoifmatorn on the internet isn't hopeless after all.

#8 By 0ZT5vs4KF0R (188.143.232.12) on 2013-07-28 07:36

<a href="http://ralxxkwmkrcrnji.com">claagyigdikzfqo</a> http://rotqqieyufcwgdg.com [url=http://nrklbgmofpmxnnq.com]tcaqwyvkbyrgtml[/url]

#7 By dmujkskwhg (94.102.52.87) on 2010-06-14 15:38

tnpqcicv elttrynm iqlirgwe

#6 By NlkyIjcNBR (95.169.190.71) on 2009-08-01 09:13

bsysoekt qjwcetov zlrxgcoh

#5 By zicSAjKEaWf (95.169.190.71) on 2009-07-31 18:00

aemwrsnw yetsybsa gvvnipyf

#4 By pvAmShdTVkagbM (95.169.190.71) on 2009-07-31 16:20

djqdltet ofinhqdh znzgvbrt

#3 By qpFgAYSLVwtgDP (95.169.190.71) on 2009-07-31 13:47

YfU8el ggxmqfsj hclzsvcx qpsdkamq

#2 By EQuoXcUR (89.248.172.50) on 2009-07-21 11:40

ดีครับ เทอมหน้าได้เรียนแน่นอน

#1 By hellooak on 2005-07-20 21:43