为什么有out参数存在?

一、原因?

=》

如果要返回单个元素,可以直接返回

复制代码
int getParms()
{}

如果返回多个同类型元素,可以使用数组,

复制代码
public int[] GetNumbers()
{
    int[] numbers = { 1, 2, 3, 4, 5 };
    return numbers;
}

如果要返回不同类型的元素,怎么办?

比如:返回一个bool类型,一个int类型。out参数的功能就是在此(不说复合类型struct)

复制代码
// C# 1.0时期(2002年),没有好的多返回值方案
public bool TryParse(string s, out int result)
{
    // 当时这是唯一的选择
}

二、现代C#中更好的替代方案

1. 元组(C# 7.0+,推荐)

复制代码
// 替代out参数的最佳选择
public (bool Success, int Result) TryParseInt(string input)
{
    if (int.TryParse(input, out int result))
        return (true, result);
    return (false, 0);
}

// 调用更清晰
var (success, value) = TryParseInt("123");
if (success)
{
    Console.WriteLine($"值为: {value}");
}

2. 记录类型/自定义类型(语义清晰)

复制代码
public record ParseResult(bool Success, int Value);

public ParseResult ParseString(string input)
{
    if (int.TryParse(input, out int result))
        return new ParseResult(true, result);
    return new ParseResult(false, 0);
}

// 使用
var result = ParseString("123");
if (result.Success)
{
    // 使用 result.Value
}

3. 模式匹配(C# 8.0+)

复制代码
public int? TryParseInt(string input)
{
    return int.TryParse(input, out int result) ? result : null;
}

// 使用
if (TryParseInt("123") is int value)
{
    Console.WriteLine(value);
}

4. 返回对象或集合

复制代码
// 返回复杂对象
public class CalculationResult
{
    public int Quotient { get; init; }
    public int Remainder { get; init; }
    public bool IsValid { get; init; }
}

public CalculationResult Divide(int a, int b)
{
    if (b == 0)
        return new CalculationResult { IsValid = false };
    
    return new CalculationResult
    {
        Quotient = a / b,
        Remainder = a % b,
        IsValid = true
    };
}

什么时候仍然需要 使用out

1. 维护现有API的兼容性

复制代码
// 必须与现有的TryParse模式保持一致
public interface IMyParser
{
    bool TryParse(string input, out MyType result);
}

2. 性能极端敏感的代码

复制代码
// 极少数情况,避免分配额外的内存
public void ProcessSpan(ReadOnlySpan<byte> source, out int processedBytes)
{
    // 高度优化的代码
    processedBytes = CalculateBytes(source);
}

3. 与外部代码交互

复制代码
// 调用Windows API或COM组件
[DllImport("user32.dll")]
public static extern bool GetCursorPos(out Point lpPoint);

现代建议

避免使用out的情况

复制代码
// 不推荐 - 使用元组更好
public void Calculate(int a, int b, 
    out int sum, out int diff, out int product, out int quotient)
{
    sum = a + b;
    diff = a - b;
    product = a * b;
    quotient = a / b;
}

推荐的做法

复制代码
// 推荐1:使用元组
public (int Sum, int Difference, int Product, int Quotient) 
    Calculate(int a, int b)
{
    return (a + b, a - b, a * b, a / b);
}

// 推荐2:使用模式匹配
public int? SafeParse(string input) => 
    int.TryParse(input, out int result) ? result : null;

// 推荐3:使用记录类型
public record CalculationResults(
    int Sum, int Difference, int Product, int Quotient);

总结

直接回答你的问题 :C#中并不一定要用 out参数。它主要是:

  1. 历史遗留:早期版本的C#缺少更好的多返回值方案

  2. 兼容性保持与现有.NET API的一致性

  3. 特殊情况:性能极端敏感或与外部代码交互

现代C#开发建议

  • 优先使用元组(C# 7.0+)

  • 考虑记录类型获得更好的语义

  • 只在必须时使用out(如实现特定接口或保持兼容)

  • 永远不要为了"性能"而盲目使用out(先测量,再优化)

out参数在现代C#中更像是一种"向后兼容"的特性,而不是首选的编程模式。新的代码库应该优先考虑使用更现代、更清晰的替代方案。

相关推荐
Ray Liang13 小时前
用六边形架构与整洁架构对比是伪命题?
java·python·c#·架构设计
Scout-leaf4 天前
WPF新手村教程(三)—— 路由事件
c#·wpf
用户298698530144 天前
程序员效率工具:Spire.Doc如何助你一键搞定Word表格排版
后端·c#·.net
mudtools5 天前
搭建一套.net下能落地的飞书考勤系统
后端·c#·.net
玩泥巴的5 天前
搭建一套.net下能落地的飞书考勤系统
c#·.net·二次开发·飞书
唐宋元明清21885 天前
.NET 本地Db数据库-技术方案选型
windows·c#
郑州光合科技余经理5 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
lindexi5 天前
dotnet DirectX 通过可等待交换链降低输入渲染延迟
c#·directx·d2d·direct2d·vortice
feifeigo1235 天前
matlab画图工具
开发语言·matlab
dustcell.5 天前
haproxy七层代理
java·开发语言·前端