当我必须编写返回两个值的方法时,我通常会按照以下代码返回List<string>
。或者,如果我必须返回,例如 id和字符串,然后我返回List<object>
,然后使用索引编号和重新创建值选择它们。
这种通过索引进行重铸和引用似乎不够优雅,所以我想为返回两个值的方法开发一种新习惯。最好的模式是什么?
using System;
using System.Collections.Generic;
using System.Linq;
namespace MultipleReturns
{
class Program
{
static void Main(string[] args)
{
string extension = "txt";
{
List<string> entries = GetIdCodeAndFileName("first.txt", extension);
Console.WriteLine("{0}, {1}", entries[0], entries[1]);
}
{
List<string> entries = GetIdCodeAndFileName("first", extension);
Console.WriteLine("{0}, {1}", entries[0], entries[1]);
}
Console.ReadLine();
}
/// <summary>
/// gets "first.txt", "txt" and returns "first", "first.txt"
/// gets "first", "txt" and returns "first", "first.txt"
/// it is assumed that extensions will always match
/// </summary>
/// <param name="line"></param>
public static List<string> GetIdCodeAndFileName(string line, string extension)
{
if (line.Contains("."))
{
List<string> parts = line.BreakIntoParts(".");
List<string> returnItems = new List<string>();
returnItems.Add(parts[0]);
returnItems.Add(line);
return returnItems;
}
else
{
List<string> returnItems = new List<string>();
returnItems.Add(line);
returnItems.Add(line + "." + extension);
return returnItems;
}
}
}
public static class StringHelpers
{
public static List<string> BreakIntoParts(this string line, string separator)
{
if (String.IsNullOrEmpty(line))
return null;
else
{
return line.Split(new string[] { separator }, StringSplitOptions.None).Select(p => p.Trim()).ToList();
}
}
}
}
好的,感谢所有人,我最喜欢“返回自定义类”的答案,从未真正认为out
易于阅读,看起来像一个hack让我以一种方式返回第一个变量而另一个变量另一个,这里是我的重构返回一个自定义类:
using System;
using System.Collections.Generic;
using System.Linq;
namespace MultipleReturns
{
class Program
{
static void Main(string[] args)
{
string extension = "txt";
{
IdCodeFileNamePair pair = GetIdCodeAndFileName("first.txt", extension);
Console.WriteLine("{0}, {1}", pair.IdCode, pair.FileName);
}
{
IdCodeFileNamePair pair = GetIdCodeAndFileName("first", extension);
Console.WriteLine("{0}, {1}", pair.IdCode, pair.FileName);
}
Console.ReadLine();
}
/// <summary>
/// gets "first.txt", "txt" and returns "first", "first.txt"
/// gets "first", "txt" and returns "first", "first.txt"
/// it is assumed that extensions will always match
/// </summary>
/// <param name="line"></param>
public static IdCodeFileNamePair GetIdCodeAndFileName(string line, string extension)
{
if (line.Contains("."))
{
List<string> parts = line.BreakIntoParts(".");
List<string> returnItems = new List<string>();
return new IdCodeFileNamePair { IdCode = parts[0], FileName = line };
}
else
{
List<string> returnItems = new List<string>();
return new IdCodeFileNamePair { IdCode = line, FileName = line + "." + extension };
}
}
}
public static class StringHelpers
{
public static List<string> BreakIntoParts(this string line, string separator)
{
if (String.IsNullOrEmpty(line))
return null;
else
{
return line.Split(new string[] { separator }, StringSplitOptions.None).Select(p => p.Trim()).ToList();
}
}
}
public class IdCodeFileNamePair
{
public string IdCode { get; set; }
public string FileName { get; set; }
}
}
答案 0 :(得分:12)
我更喜欢创建一个包含两个属性的轻量级类(见下文),或者使用一个元组(现在可以在.NET 4中加入框架但不难编写自己的元组)
class MyReturnValue
{
public string Id { get; set; }
public string Name { get; set; }
}
答案 1 :(得分:8)
您可以从4.0开始返回tuple。
答案 2 :(得分:2)
答案 3 :(得分:2)
另一种选择是返回KeyValuePair<int, string>
。
答案 4 :(得分:1)
为什么不public static void GetIdCodeAndFileName(string line, string extension, out string id, out string fileName)
?
答案 5 :(得分:1)
我要么使用params,要么创建一个带有属性的结构(对于属性初始化器语法)并返回它。创建自定义结构/类具有可变命名的优点,可以匹配传递的数据。这使代码更具可读性。
IdAndString GetIDAndString()
{
return new IdAndString()
{
ID = 1,
Str = "123"
};
}
struct IdAndString
{
public int ID { get; set; }
public string Str { get; set; }
}
答案 6 :(得分:1)
我建议使用Mark建议的轻量级物体。但也有其他模式。
另一个简单的方法是,使用reference by reference属性。同样,调用者发送一个空数组作为参数,该数组将由函数填充。
答案 7 :(得分:0)
模板Pair<T,V>
怎么样?当然,如果相同的数据类型将被传递,你可以为它构建自定义数据类型,但它不是通用的。
(或者也许C#允许您即时生成类?更新:确定忽略此位)
答案 8 :(得分:0)
简单来说,在C#中返回两个值并不是一种优雅的方式。虽然我绝对认为使用out
参数比返回List
更好,但这不是很易于维护或可读。 C#开发人员期望out
,它直接受语言支持,并且很清楚它正在做什么。
从4.0开始,您可以使用Tuple
代替。