Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

การใช้คีย์เวิร์ด new ใน C#

คีย์เวิร์ด 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 เมื่อเป็นไปได้
  • หลีกเลี่ยง new Modifier (Hiding) - ใช้ override + virtual แทน เพื่อ Polymorphism
  • ถ้าจำเป็นต้อง Hiding ให้ใส่ new อย่างชัดเจน (Compiler จะเตือนถ้าไม่ใส่)
  • Struct ไม่จำเป็นต้อง new (มี Default Constructor อัตโนมัติ) แต่แนะนำให้ใช้เพื่อ Clarity