ใน C# มีออปเปอเรเตอร์ 2 ตัวสำหรับการทำงานกับชนิดข้อมูล (Type) คือ is และ as ซึ่งมีวัตถุประสงค์และพฤติกรรมต่างกัน
IS Operator - Type Checking
is ใช้ **ตรวจสอบว่า Object เป็นชนิดข้อมูลที่กำหนดหรือไม่** คืนค่า bool (true/false) ไม่ได้ทำการ Cast
Syntax
expr is type
ตัวอย่างพื้นฐาน
using System;
class One { }
class Two { }
public class Demo {
public static void Test(object obj) {
if (obj is One) {
Console.WriteLine("Class One");
One x = (One)obj; // Cast แยกต่างหาก
} else if (obj is Two) {
Console.WriteLine("Class Two");
Two y = (Two)obj;
} else {
Console.WriteLine("None of the classes!");
}
}
public static void Main() {
One o1 = new One();
Two t1 = new Two();
Test(o1); // Class One
Test(t1); // Class Two
Test("str"); // None of the classes!
Console.ReadKey();
}
}
ผลลัพธ์
Class One
Class Two
None of the classes!
Pattern Matching (C# 7+) - is แบบทันสมัย
// Type Pattern - Check และ Cast พร้อมกัน
if (obj is One one) { // one พร้อมใช้งานทันที
Console.WriteLine(one.GetType().Name);
}
// Property Pattern (C# 8+)
if (person is { Age: >= 18, Name: not null }) {
Console.WriteLine("Adult");
}
// Switch Expression (C# 8+)
string result = obj switch {
One o => "One",
Two t => "Two",
string s => $"String: {s}",
_ => "Unknown"
};
AS Operator - Safe Casting
as ใช้ **แปลงชนิดข้อมูล (Cast) อย่างปลอดภัย** ถ้าแปลงไม่ได้ จะคืนค่า null แทนที่จะโยน Exception
Syntax
expression as type
ข้อจำกัด
- ใช้ได้กับ **Reference Types** และ **Nullable Value Types** เท่านั้น
- ไม่สามารถใช้กับ Non-nullable Value Types (
int,double,struct) ได้ - ทำได้เฉพาะ Reference Conversion, Boxing/Unboxing, Nullable Conversion
- ไม่ทำ User-defined Conversions ได้ (ต้องใช้ Cast แบบปกติ
(Type)expr)
ตัวอย่างพื้นฐาน
using System;
public class Demo {
public static void Main() {
object[] obj = new object[2];
obj[0] = "jack";
obj[1] = 32; // int (boxed)
for (int i = 0; i < obj.Length; i++) {
string s = obj[i] as string; // Safe cast
Console.Write("{0}: ", i);
if (s != null)
Console.WriteLine("'" + s + "'");
else
Console.WriteLine("This is not a string!");
}
Console.ReadKey();
}
}
ผลลัพธ์
0: 'jack'
1: This is not a string!
as กับ Nullable Value Types
object boxedInt = 42;
int? nullable = boxedInt as int?; // OK - Nullable Value Type
object boxedString = "hello";
int? nullable2 = boxedString as int?; // null (ไม่ใช่ exception)
IS vs AS - สรุปความแตกต่าง
| ด้าน | is Operator | as Operator |
|---|---|---|
| วัตถุประสงค์ | Type Checking (True/False) | Safe Casting (Result or Null) |
| คืนค่า | bool |
Type ที่ระบุ หรือ null |
| Performance | เร็ว (แค่ Check) | ช้ากว่าเล็กน้อย (Check + Cast) |
| Null Handling | null is Type = false |
null as Type = null |
| Value Types | ได้ (Boxing) | ได้เฉพาะ Nullable |
| Pattern Matching | รองรับเต็มรูปแบบ | ไม่รองรับ |
Best Practices
- ใช้ is (Pattern Matching) เมื่อต้อง Check และ Cast พร้อมกัน - Clean และ Safe
- ใช้ as เมื่อคาดหวังว่าอาจจะ Cast ไม่ได้ และต้องการ Handle Null เอง
- หลีกเลี่ยง
(Type)obj(C-style Cast) ที่โยน Exception - ใช้is+ Cast หรือasแทน - สำหรับ Value Types ใช้
is int iหรือobj is intแทนas