为什么有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#中更像是一种"向后兼容"的特性,而不是首选的编程模式。新的代码库应该优先考虑使用更现代、更清晰的替代方案。

相关推荐
飞天遇见妞2 小时前
C/C++中宏定义的使用
c语言·开发语言·c++
雨落在了我的手上2 小时前
C语言入门(三十二):预处理详解(2)
c语言·开发语言
应用市场2 小时前
基于 C# WinForms 的 Windows 系统监控工具开发实战
windows·单片机·c#
专注API从业者2 小时前
构建企业级 1688 数据管道:商品详情 API 的分布式采集与容错设计
大数据·开发语言·数据结构·数据库·分布式
疏狂难除2 小时前
windows上使用LLVM编译lua
开发语言·lua
沐知全栈开发2 小时前
XML Schema 复合元素 - 仅含文本
开发语言
代码游侠2 小时前
复习——线程(pthread)
linux·运维·开发语言·网络·学习·算法
alanesnape2 小时前
Java异常处理详解:Exception、ArithmeticException、FileNotFoundException
java·开发语言