首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C# 方法多返回值:out/ref 之外的 5 種現代方案

     編輯:程式設計綜合問答

方案對比

方案語法適用場景優點缺點
1. Tuple 元組 (C# 7+)`(int sum, int count) Calc()`2~7 個相關值、臨時組合語法糖、解構賦值、無額外類型字段名僅編譯期有效、跨程序集需注意
2. 自定義類/結構體`class Result { public int A; public int B; }`語義明確、復用、需驗證/方法強類型、可擴展、文檔友好樣板代碼多、堆分配(class)
3. 匿名類型`return new { X = 1, Y = 2 };`內部邏輯、LINQ 投影極簡潔編譯期類型、不可跨方法邊界返回
4. 引用類型參數傳遞`void Calc(List<int> buffer)`大數據填充、避免拷貝零分配、可變長副作用隱蔽、需約定調用者初始化
5. 模式匹配 + out var (C# 7+)`if (TryParse(s, out var n))`嘗試操作、失敗不拋異常語義清晰、配合模式匹配仍屬 out 變體

代碼示例

1. Tuple(推薦首選)

public (int Sum, int Count, double Avg) Stats(int[] nums)
{
    int sum = 0, count = 0;
    foreach (var n in nums) { sum += n; count++; }
    return (sum, count, count > 0 ? (double)sum / count : 0);
}

// 調用
var (s, c, a) = Stats(new[] {1,2,3,4,5});
Console.WriteLine($"{s} {c} {a}"); // 15 5 3

2. 結構體(高性能、值語義)

public readonly struct Point3D
{
    public double X { get; }
    public double Y { get; }
    public double Z { get; }
    public Point3D(double x, double y, double z) => (X, Y, Z) = (x, y, z);
    public void Deconstruct(out double x, out double y, out double z) => (x, y, z) = (X, Y, Z);
}

public Point3D Centroid(Point3D[] pts)
{
    double x=0, y=0, z=0;
    foreach (var p in pts) { x+=p.X; y+=p.Y; z+=p.Z; }
    int n = pts.Length;
    return new Point3D(x/n, y/n, z/n);
}

3. 類(引用語義、可為 null、可繼承)

public class OperationResult
{
    public bool Success { get; set; }
    public string Message { get; set; }
    public object Data { get; set; }
    public static OperationResult Ok(object data = null) => new() { Success = true, Data = data };
    public static OperationResult Fail(string msg) => new() { Success = false, Message = msg };
}

4. 異步多返回

public async Task<(bool Ok, string Token)> LoginAsync(string user, string pwd)
{
    var resp = await _http.PostAsJsonAsync("/login", new { user, pwd });
    if (resp.IsSuccessStatusCode)
        return (true, await resp.Content.ReadAsStringAsync());
    return (false, await resp.Content.ReadAsStringAsync());
}

選型建議

  • **臨時、局部、2~4 個值** → **Tuple**,最省事。
  • **業務實體、需驗證、跨層傳遞** → **類/結構體**,可維護性最強。
  • **高性能熱路徑、大數組填充** → **引用參數 / `Span` / `Memory`**。
  • **舊代碼遷移** → `out`/`ref` 仍可用,但新代碼優先 Tuple。

避坑指南

  • ❌ Tuple 字段名在反射/序列化中可能丟失(編譯器擦除),跨程序集用 `[TupleElementNames]` 或改用類。
  • ❌ 匿名類型**不能**作為方法返回類型(只能 `object`/`dynamic`,失去類型安全)。
  • ❌ `out` 參數要求調用前**確定賦值**,易忘賦值導致編譯錯誤。

總結

C# 7+ 後,**Tuple 元組是多返回值的首選**:語法原生、解構優雅、零開銷(值類型)。複雜業務用 **readonly struct**(值語義、不可變、高性能)或 **class**(引用語義、可擴展)。合理選擇,代碼既簡潔又專業。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved