函数是否可以返回两个值?

函数是否可以返回两个值? 如果两个值都是相同的类型,则可以使用数组,但是如何返回两个不同的类型值?

函数可以返回2个单独的值吗? 不,C#中的函数只能返回单个值。

虽然可以使用其他概念来返回2个值。 首先想到的是使用包装类型,例如Tuple

 Tuple GetValues() { return Tuple.Create(42,"foo"); } 

Tuple类型仅适用于4.0及更高版本。 如果您使用的是早期版本的框架,您可以创建自己的类型或使用KeyValuePair

 KeyValuePair GetValues() { return new KeyValuePair(42,"foo"); } 

另一种方法是使用out参数(我会高度推荐元组方法)。

 int GetValues(out string param1) { param1 = "foo"; return 42; } 

总之,没有。

但是你可以为此定义一个struct (或class ):

 struct TwoParameters { public double Parameter1 { get; private set; } public double Parameter2 { get; private set; } public TwoParameters(double param1, double param2) { Parameter1 = param1; Parameter2 = param2; } } 

这当然对于单个问题来说太具体了。 一种更灵活的方法是定义一个通用structTuple (如JaredPar建议的那样):

 struct Tuple { public T1 Property1 { get; private set; } public T2 Property2 { get; private set; } public Tuple(T1 prop1, T2 prop2) { Property1 = prop1; Property2 = prop2; } } 

(注意,与上述非常相似的东西实际上是4.0及更高版本中.NET的一部分,显然。)

那你可能有一些看起来像这样的方法:

 public Tuple GetPriceAndVolume() { double price; int volume; // calculate price and volume return new Tuple(price, volume); } 

代码如下:

 var priceAndVolume = GetPriceAndVolume(); double price = priceAndVolume.Property1; int volume = priceAndVolume.Property2; 

这不是直接可能的。 您需要返回一个包装这两个参数的参数,或者使用out参数:

 object Method(out object secondResult) { //... 

要么:

 KeyValuePair Method() { // .. 

所有可能的解决方案都错过了一个重点; 为什么要从方法返回两个值? 我看到它的方式,有两种可能的情况; a)你正在返回两个真正应该封装在一个对象中的值(例如,某些东西的高度和宽度,所以你应该返回一个代表那个东西的对象)或者b)这是一个代码味道,你真的需要考虑为什么该方法返回两个值(例如,该方法实际上做了两件事)。

不是直接的。 您可以选择返回某种自定义结构或具有多个属性的类,如果您只想返回两个值,则使用KeyValuePair ,或者使用out参数 。

您基本上(至少)有两个选项,要么除了函数的返回值之外还要创建一个out参数,比如T1 Function(out T2 second)或者你自己的类将这两种类型放在一起,类似于Pair 。 我个人更喜欢第二种方式,但这是你的选择。

在C#中,您可以使用out参数返回多个值。 请参阅Int32 struct的TryParse方法中的示例。 它返回bool和out参数中的整数。

不,但你可以使用out参数

  int whatitis; string stuff = DoStuff(5, out whatitis); public string DoStuff(int inParam, out int outParam) { outParam = inParam + 10; return "donestuff"; } 

使用C#7 ,您现在可以返回ValueTuple

 static (bool success, string value) GetValue(string key) { if (!_dic.TryGetValue(key, out string v)) return (false, null); return (true, v); // this is a ValueType literal } static void Main(string[] args) { var (s, v) = GetValue("foo"); // (s, v) desconstructs the returned tuple if (s) Console.WriteLine($"foo: {v}"); } 

ValueTuple是一个值类型,与参考类型的Tuple相比,它使得它成为返回值的绝佳选择 – 不需要对象进行垃圾回收。

另请注意,您可以为返回的值指定名称。 真的很好。

仅仅因为这个原因,我希望可以只用一个元素声明一个ValueTuple 。 唉,不允许:

 static (string error) Foo() { // ... does not work: ValueTuple must contain at least two elements } 

除非返回包含多个值的类型(Struct,Dictionary等),否则无法从函数返回多个值。 唯一的另一种方法是在传入参数上使用“out”或“ref”关键字。

您可以使用out参数。

 int maxAge; int minAge; public int GetMaxAgeAndMinAge(out int maxAge, out int minAge) { MaxAge = 60; MinAge = 0; return 1; //irrelevant for this example since we care about the values we pass in } 

我真的倾向于远离这个,我认为这是一种代码味道。 它适用于快速和脏。 一种更可测试且更好的方法是传递代表您的域的对象(需要查看两个这两个值)。

你可以试试这个

 public IEnumerable Get() { return new string[] { "value1", "value2" }; } 

要返回2个值,我通常使用http://blog.oxt.com/2007/07/16/generic-pair-net-class/中的 Pair类。 如果需要从描述范围的方法2值返回,例如From / To或Min / Max,则可以使用FromToRange类 。

 public class FromToRange { public T From { get; set; } public T To { get; set; } public FromToRange() { } public FromToRange(T from, T to) { this.From = from; this.To = to; } public override string ToString() { string sRet = String.Format("From {0} to {1}", From, To); return sRet; } public override bool Equals(object obj) { if (this == obj) return true; FromToRange pair = obj as FromToRange; if (pair == null) return false; return Equals(From, pair.From) && Equals(To, pair.To); } public override int GetHashCode() { return (From != null ? From.GetHashCode() : 0) + 29 * (To != null ? To.GetHashCode() : 0); } }