Reflection #1 : Class Type

    Editor ที่เราใช้เขียนโปรแกรมในยุคปัจจุบัน มีไม่น้อยที่รองรับความสามารถแบบ IntelliSense ซึ่งวิธีการทำ IntelliSense ของ Editor ทั่วไปมีอยู่ 2 วิธีคือ วิธีแรก Editor จะมีฐานข้อมูลของตัวเอง เมื่อเวลาเราพิมพ์เครื่องหมาย . มันจะเอาคำข้างหน้าไปค้นหาใน ฐานข้อมูล เพื่อดึงเอารายชื่อ Methods/properties ขึ้นมาแสดงให้เราเลือก ส่วนวิธีที่ 2 กลับไม่เก็บฐานข้อมูล แต่หากใช้กลไกที่เรียกว่า Reflection ซึ่งเป็นความสามารถของภาษาคอมพิวเตอร์ร่วมสมัย เพื่อดึงข้อมูลมาแสดง

    ผมคงข้ามเรื่อง Reflection ไปก่อน ก่อนที่เราจะทำความเข้าใจเกี่ยวกับ Reflection ในบทต่อๆ ไป ผมต้องปูพื้นฐานกันก่อน ใน .NET Framework จะมี class ตัวหนึ่ง ซึ่งเก็บนิยามของ class อื่นๆ ฟังดูแปลกๆ นะครับ เพื่อความเข้าใจ เรามาลองดูตัวอย่างนี้ก่อนครับ

Type t = typeof(int);
Console.WriteLine(t.Name);

จากตัวอย่างนี้ เราจะได้ผลลัพธ์  Int32 มาดูกันครับว่าทำไมถึงได้ผลลัพธ์เช่นนั้น เริ่มที่ ในแต่ละ class ของ .NET Framework จะมีการแอบสร้าง class ที่เก็บรายละเอียดของ class นั้น รายละเอียดที่เก็บ ก็คือ ชื่อ class, methods, properites และอื่นๆ ของ class

class ที่เก็บรายละเอียดนี้ล้วนแล้วแต่ Inherit มาจาก class ที่ชื่อว่า Type ทั้งสิ้น ดังนั้นถ้าเราต้องการดูรายละเอียดของ class int เราก็ใช้ Syntax ข้างบนเพื่อดึงเอาข้อมูลออกมา

หรือถ้าเราได้มาเป็นตัวแปร เราสามารถใช้แบบนี้ก็ได้ครับ

int num = 5;
Type t = num.GetTypes);
Console.WriteLine(t.Name);

ผมคงไม่อธิบายรายละเอียดมาก ถ้าคุณสนใจว่าใน class Type มีอะไรให้เราเรียกใช้บ้าง คุณสามารถดูได้จาก Online Help อยู่แล้ว แต่เพื่อความเข้าใจ ผมขอแสดงโปรแกรมตัวอย่างให้เห็น ซึ่งเป็นวิธีเดียวกันกับที่พวก Editor ทำ IntelliSense กันครับ

 

ShowMethods.cs

using System;
using System.Reflection;
class ShowMethods
{ 	
	public static void ShowMethods(Type t)
	{
		foreach (MethodInfo m in t.GetMethods() ) {
			string str = "";
			if (m.IsPublic) str = "public ";
			if (m.IsPrivate) str = "private ";
			if (m.IsAbstract) str += "abstract ";
			if (m.IsStatic) str += "static ";
			str += m.ReturnType.Name + " ";
			str += m.Name + "(";			
			foreach (ParameterInfo p in m.GetParameters() ) {
				str += p.ParameterType.Name + " ";
				if (p.IsOut) str += ("out ");
				if (p.IsRetval) str += ("ref ");
				str += p.Name + ", ";
			}		 
			char lastchar = str[str.Length - 1];
			if (lastchar == ' ') {
				str = str.Substring(0, str.Length-2);
			}
			str += ")";
			Console.WriteLine(str);
		}	
	}
	public static void Main()
	{
		ShowMethods(typeof(Console));
	}
}

เมื่อรันแล้วจะได้ผลลัพธ์ดังนี้ครับ

DOS Prompt

C:\CS> ShowMethods

public Int32 GetHashCode()
public Boolean Equals(Object obj)
public String ToString()
public static TextWriter get_Error()
public static TextReader get_In()
public static TextWriter get_Out()
public static Stream OpenStandardError()
public static Stream OpenStandardError(Int32 bufferSize)
public static Stream OpenStandardInput()
public static Stream OpenStandardInput(Int32 bufferSize)
public static Stream OpenStandardOutput()
public static Stream OpenStandardOutput(Int32 bufferSize)
public static Void SetIn(TextReader newIn)
public static Void SetOut(TextWriter newOut)
public static Void SetError(TextWriter newError)
public static Int32 Read()
public static String ReadLine()
public static Void WriteLine()
public static Void WriteLine(Boolean value)
public static Void WriteLine(Char value)
public static Void WriteLine(Char[] buffer)
public static Void WriteLine(Char[] buffer, Int32 index, Int32 count)
public static Void WriteLine(Decimal value)
public static Void WriteLine(Double value)
public static Void WriteLine(Single value)
public static Void WriteLine(Int32 value)
public static Void WriteLine(UInt32 value)
public static Void WriteLine(Int64 value)
public static Void WriteLine(UInt64 value)
public static Void WriteLine(Object value)
public static Void WriteLine(String value)
public static Void WriteLine(String format, Object arg0)
public static Void WriteLine(String format, Object arg0, Object arg1)
public static Void WriteLine(String format, Object arg0, Object arg1, Object arg2)
public static Void WriteLine(String format, Object arg0, Object arg1, Object arg2, Object arg3)
public static Void WriteLine(String format, Object[] arg)
public static Void Write(String format, Object arg0)
public static Void Write(String format, Object arg0, Object arg1)
public static Void Write(String format, Object arg0, Object arg1, Object arg2)
public static Void Write(String format, Object arg0, Object arg1, Object arg2, Object arg3)
public static Void Write(String format, Object[] arg)
public static Void Write(Boolean value)
public static Void Write(Char value)
public static Void Write(Char[] buffer)
public static Void Write(Char[] buffer, Int32 index, Int32 count)
public static Void Write(Double value)
public static Void Write(Decimal value)
public static Void Write(Single value)
public static Void Write(Int32 value)
public static Void Write(UInt32 value)
public static Void Write(Int64 value)
public static Void Write(UInt64 value)
public static Void Write(Object value)
public static Void Write(String value)
public Type GetType()

C:\CS>_

MethodInfo() และ ParameterInfo() อยู่ภายใต้ NameSpace System.Reflection เพื่อความสะดวกผมเลย ใช้ using System.Reflection ครับ