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

การปรับปรุง Out Parameter ใน C# 7.0

เราสามารถประกาศ Out Variables แบบ Inline ได้ใน Argument List ของ Method ที่ใช้ แทนที่จะเขียน Declaration Statement แยกต่างหาก

Existing Out Parameters ได้รับการปรับปรุงใน Version นี้ ตอนนี้เราสามารถประกาศ Out Variables ใน Argument List ของ Method Call ได้

ข้อดี

  • Code อ่านง่ายขึ้น
  • ไม่ต้อง Assign Initial Value
  • Scope จำกัดอยู่ใน Block ที่ Call (Safe)

Existing Syntax (ก่อน C# 7.0)


class Program {
    public static void AddMultiplyValues(int a, int b, out int c, out int d) {
        c = a + b;
        d = a * b;
    }
    
    public static void Main() {
        int c;  // ต้องประกาศก่อน
        int d;  // ต้องประกาศก่อน
        AddMultiplyValues(5, 10, out c, out d);
        Console.WriteLine(c);  // 15
        Console.WriteLine(d);  // 50
        Console.ReadLine();
    }
}

Output


15
50

New Syntax (C# 7.0+)


class Program {
    public static void AddMultiplyValues(int a, int b, out int c, out int d) {
        c = a + b;
        d = a * b;
    }
    
    public static void Main() {
        // Inline Declaration: out int c, out int d
        AddMultiplyValues(5, 10, out int c, out int d);
        Console.WriteLine(c);  // 15
        Console.WriteLine(d);  // 50
        Console.ReadLine();
    }
}

Output


15
50

ตัวอย่างเพิ่มเติม: TryParse Pattern


// ก่อน C# 7.0
int number;
if (int.TryParse(input, out number)) {
    Console.WriteLine($"Parsed: {number}");
}

// C# 7.0+ Inline
if (int.TryParse(input, out int number)) {
    Console.WriteLine($"Parsed: {number}");
}
// number Scope อยู่ใน if block เท่านั้น

// หลาย Out Parameters
if (DateTime.TryParseExact(input, "yyyy-MM-dd", null, 
    System.Globalization.DateTimeStyles.None, out DateTime date)) {
    Console.WriteLine($"Date: {date:d}");
}

ใช้กับ Var (Type Inference)


// Var กับ Out (C# 7.0+)
if (double.TryParse(input, out var result)) {
    Console.WriteLine($"Result: {result}");
}

// Tuple Return Alternative (Modern Approach)
public (bool Success, int Value) TryParseInt(string input) {
    return int.TryParse(input, out int value) 
        ? (true, value) 
        : (false, 0);
}

// Usage
var (success, value) = TryParseInt("123");
if (success) Console.WriteLine(value);

Out Variables Scope


void Demo() {
    // Out Variable Scope: ใน Block เดียวกับ Declaration
    if (int.TryParse("123", out int x)) {
        Console.WriteLine(x); // OK
    }
    // Console.WriteLine(x); // Error: x ไม่อยู่ใน Scope
    
    // แต่ถ้า Declaration อยู่ข้างนอก
    int.TryParse("456", out int y);
    Console.WriteLine(y); // OK: y อยู่ใน Method Scope
}

Best Practices

  • ใช้ Inline out var หรือ out Type สำหรับ TryParse Patterns
  • หลีกเลี่ยง Out Parameters ใน Public APIs ใหม่ (ใช้ Tuple Returns หรือ Result Types แทน)
  • Out Parameters ยังคงเหมาะสำหรับ: TryGetValue, TryParse, TryDequeue Patterns
  • ใน Async Methods: Out Parameters ไม่ได้ (ใช้ Tuple/ValueTuple)

Modern Alternative: Result Pattern


// แทน Out Parameters
public Result GetUser(int id) {
    if (!_users.TryGetValue(id, out var user)) 
        return Result.Fail("Not found");
    return Result.Ok(user);
}

// Usage
var result = GetUser(1);
if (result.IsSuccess) {
    Console.WriteLine(result.Value.Name);
} else {
    Console.WriteLine(result.Error);
}