คีย์เวิร์ด new ใน C# มี **3 การใช้งานหลัก** ที่แตกต่างกันอย่างสิ้นเชิง:
1. new Operator - สร้าง Instance (Object Creation)
ใช้สร้าง Instance ของ Class, Struct, Array, Delegate
// Class
var person = new Person();
// Struct (Value Type) - ไม่ต้อง new ก็ได้ แต่แนะนำให้ new
var point = new Point(10, 20);
// Array
int[] numbers = new int[5]; // Fixed size
int[] numbers2 = new int[] { 1, 2, 3 }; // With initializer
var numbers3 = new[] { 1, 2, 3 }; // Implicitly typed
// Delegate
Action action = new Action(() => Console.WriteLine("Hello"));
ตัวอย่างจากต้นฉบับ (แก้ไขให้ถูกต้อง)
using System;
namespace CalculatorApplication {
class NumberManipulator {
public void Swap(int x, int y) {
int temp = x;
x = y;
y = temp;
// ⚠️ นี้เปลี่ยนค่า Local Parameter เท่านั้น ไม่ส่งผลกลับไป!
}
// ถ้าต้องการ Swap จริง ใช้ ref
public void SwapRef(ref int x, ref int y) {
int temp = x;
x = y;
y = temp;
}
}
class Program {
static void Main(string[] args) {
// ใช้ new สร้าง Instance
NumberManipulator n = new NumberManipulator();
int a = 100;
int b = 200;
Console.WriteLine($"Before swap: a={a}, b={b}"); // 100, 200
// ⚠️ โดยไม่มี ref - ค่าไม่เปลี่ยน
n.Swap(a, b);
Console.WriteLine($"After Swap (no ref): a={a}, b={b}"); // 100, 200
// ใช้ ref - ค่าเปลี่ยนจริง
n.SwapRef(ref a, ref b);
Console.WriteLine($"After SwapRef: a={a}, b={b}"); // 200, 100
Console.ReadLine();
}
}
}
ผลลัพธ์
Before swap: a=100, b=200
After Swap (no ref): a=100, b=200
After SwapRef: a=200, b=100
2. new Modifier - Method Hiding (Shadowing)
ใช้ใน Derived Class เพื่อ **ซ่อน (Hide)** Member ของ Base Class ที่มีชื่อเดียวกัน
public class Base {
public virtual void Display() {
Console.WriteLine("Base.Display()");
}
}
public class Derived : Base {
// ใช้ new ซ่อน Base.Display()
public new void Display() {
Console.WriteLine("Derived.Display()");
}
}
// ใช้งาน
Base b = new Derived();
b.Display(); // "Base.Display()" - เรียก Base Version (Polymorphism ไม่ทำงาน)
Derived d = new Derived();
d.Display(); // "Derived.Display()" - เรียก Derived Version
// หากต้องการ Polymorphism ใช้ override แทน new
public class Derived2 : Base {
public override void Display() { // ต้องมี virtual ใน Base
Console.WriteLine("Derived2.Display()");
}
}
3. new Constraint - Generic Constraint
ใช้ใน Generic Type Parameter ระบุว่าต้องมี **Parameterless Constructor**
// T ต้องมี Public Parameterless Constructor
public T CreateInstance() where T : new() {
return new T();
}
// ใช้งาน
var person = CreateInstance(); // Person ต้องมี public Person()
สรุป 3 รูปแบบของ new
| รูปแบบ | ชื่อ | วัตถุประสงค์ | ตัวอย่าง |
|---|---|---|---|
new Type() |
new Operator | สร้าง Object/Instance | new List<int>() |
new void Method() |
new Modifier | ซ่อน Base Class Member (Hiding) | public new void Foo() |
where T : new() |
new Constraint | Generic Constraint - ต้องมี Parameterless Constructor | class Factory<T> where T : new() |
new() vs Activator.CreateInstance()
// new() Constraint - Compile-time Check, Fast
public T Create() where T : new() => new T();
// Activator - Runtime, Slow, Flexible
public T CreateActivator() => (T)Activator.CreateInstance(typeof(T));
// Expression Tree - Compile Lambda, Fast (Cache Delegate)
public static class Factory where T : new() {
public static readonly Func Create = Expression.Lambda>(
Expression.New(typeof(T))).Compile();
}
Best Practices
- ใช้
new()Constraint แทนActivator.CreateInstanceเมื่อเป็นไปได้ - หลีกเลี่ยง
newModifier (Hiding) - ใช้override+virtualแทน เพื่อ Polymorphism - ถ้าจำเป็นต้อง Hiding ให้ใส่
newอย่างชัดเจน (Compiler จะเตือนถ้าไม่ใส่) - Struct ไม่จำเป็นต้อง
new(มี Default Constructor อัตโนมัติ) แต่แนะนำให้ใช้เพื่อ Clarity