一、原因?
=》
如果要返回单个元素,可以直接返回
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参数。它主要是:
-
历史遗留:早期版本的C#缺少更好的多返回值方案
-
兼容性:保持与现有.NET API的一致性
-
特殊情况:性能极端敏感或与外部代码交互
现代C#开发建议:
-
优先使用元组(C# 7.0+)
-
考虑记录类型获得更好的语义
-
只在必须时使用
out(如实现特定接口或保持兼容) -
永远不要为了"性能"而盲目使用
out(先测量,再优化)
out参数在现代C#中更像是一种"向后兼容"的特性,而不是首选的编程模式。新的代码库应该优先考虑使用更现代、更清晰的替代方案。