ใช้ “as” ในการ “cast”
C# เป็น Strong type นั่นหมายความว่าเราควรหลีกเลี่ยงการ แปลง type เท่าที่เราจะทำได้ แต่บางครั้ง มันก็เลี่ยงไม่ได้… บางครั้งเราก็จำเป็นต้อง downcast object ไปเป็น type อื่นๆไม่เว้นกระทั่ง class หรือ interfaces เรามีทางเลือก 2ทางคือ ใช้ as operator หรือใช้ cast และเราก็มี “is” ที่ทำให้เราสามารถทดสอบก่อนว่า เราสามารถ convert ได้หรือเปล่าถ้าconvert ได้ก็ค่อยใช้ as หรือ casts
ทางเลือกที่ถูกต้องคือ ใช้ as operator ….เพราะมัน safe กว่าการ casting และมีประสิทธิภาพมากว่า ณ runtime , as และ is operators จะไม่สร้าง object ใหม่ เพื่อ satisfy a request
object o = Factory.GetObject( );
MyType t = o as MyType;
if ( t != null )
{
// work with t, it's a MyType.
} else
{
// report the failure.
}
Code ด้านบนเป้นการ ใช้ as แทนการ cast Object มาเป็น MyType ถ้าไม่สามารถ cast ได้ t จะมีค่าเป็น null
….ต่างกับ การใช้ “cast” ดัง code ด้านล่าง
object o = Factory.GetObject( );
try {
MyType t;
t = ( MyType ) o;
if ( t != null )
{
// work with T, it's a MyType.
} else
{
// Report a null reference failure.
}
} catch
{
// report the conversion failure.
}
จาก code เราต้องใส่ try/catch clause เพื่อกัน exception จากการแปลงที่ผิดพลาด ทั้งยังมี overhead อีก
สังเกตว่า การที่เราต้อง check exception จากการใช้ cast เพราะ ถ้าobject ไม่ใช่ Type ที่สามารถ cast ได้แล้ว จะเกิด InvalidCastException
[Unable to cast object of type 'Factory' to type 'MyType'.] ทันทีซึ่งเพียงแค่นี้เราก็หันมาใช้ as แทนได้แล้ว

เพราะ เราแค่check ว่า reference ที่ return มาเป็น null หรือเปล่าแค่นั้นเอง แถมไม่มี Exception มากวนใจ.
สิ่งที่แตกต่างกันอย่างมากของ as และ cast คือ as และ is operator จะพิจารณา runtime type ของ object ที่ถูก convert และจะไม่ทำอะไรอีก หาก object ไม่ได้รับ type ที่ต้องการแล้ว จะถือว่า fail ในทางกลับกัน Cast,ใช้ conversion operator เพื่อจะ convert object เป็น type ที่ ถูก request นั่นรวมถึง การทำ built-in numeric conversions เช่นการ Cast long ไปเป็น short จะทำให้เราสูญเสียข้อมูลได้
จากที่อ่านมาเราอาจสรุปได้ว่าควรใช้ as แทนการ cast แต่ยังมีกรณีที่เราไม่สามารถใช้ as ได้…
as ใช้กับ Value Type ไม่ได้ !!
value type เช่นพวกเกี่ยวกับตัวเลขทั้งหลาย int double float long ….
ใช่ครับ เราต้องกลับไปใช้ cast เหมือนเดิม แต่ไหนๆต้องใช้ทั้งทีเราก็ควรใช้ “is” เพื่อตรวจสอบ แทนการ ดัก try/catch ดังโค้ดด้านล่าง
object o = Factory.GetValue( );
int i = 0;
if ( o is int )
i = ( int ) o;
ถ้า object มีType เป็นชนิดอื่นที่ไม่ใช่ int เช่น double, operation นี้จะมีค่าเป็น false
ไม่จำเป็นต้องใช้ is ร่วมกับ as
MyType t = null;
if ( o is MyType )
t = o as MyType;
หรือ
MyType t = null;
if ( ( o as MyType ) != null )
t = o as MyType;
เพราะเราสามารถ check value ของ operation as เป็น null ง่ายกว่าเยอะ
สรุป เราควรหลีกเลี่ยง Converting Types แต่บางครั้งมันก็จำเป็น แต่ถึงกระนั้นก็ควรใช้ as และ is operators เพราะ มัน ชัดเจนกว่า การ cast ปกติ, และเราไม่ต้องคอย ดัก exception เพื่อตรวจสอบ type ที่ไม่ถูกต้อง
Tags:
as,
c#,
Casting,
effective,
programming