函数是否可以返回两个值? 如果两个值都是相同的类型,则可以使用数组,但是如何返回两个不同的类型值?
答案 0 :(得分:39)
函数可以返回2个单独的值吗?不,C#中的函数只能返回单个值。
虽然可以使用其他概念来返回2个值。首先想到的是使用包裹类型,例如Tuple<T1,T2>
。
Tuple<int,string> GetValues() {
return Tuple.Create(42,"foo");
}
Tuple<T1,T2>
类型仅适用于4.0及更高版本。如果您使用的是早期版本的框架,则可以创建自己的类型或使用KeyValuePair<TKey,TValue>
。
KeyValuePair<int,string> GetValues() {
return new KeyValuePair<int,sting>(42,"foo");
}
另一种方法是使用out参数(我会高度推荐元组方法)。
int GetValues(out string param1) {
param1 = "foo";
return 42;
}
答案 1 :(得分:13)
总之,没有。
但是你可以为此定义一个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;
}
}
这当然对于单个问题来说太具体了。更灵活的方法是定义类似struct
的通用Tuple<T1, T2>
(如JaredPar建议的那样):
struct Tuple<T1, T2> {
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<double, int> GetPriceAndVolume() {
double price;
int volume;
// calculate price and volume
return new Tuple<double, int>(price, volume);
}
这样的代码:
var priceAndVolume = GetPriceAndVolume();
double price = priceAndVolume.Property1;
int volume = priceAndVolume.Property2;
答案 2 :(得分:7)
这不是直接可能的。您需要返回一个包装这两个参数的参数,或者使用out参数:
object Method(out object secondResult)
{
//...
或者:
KeyValuePair<object,object> Method()
{
// ..
答案 3 :(得分:5)
所有可能的解决方案都错过了一个重点;为什么要从方法返回两个值?我看来,有两种可能的情况; a)你正在返回两个真正应该封装在一个对象中的值(例如,某些东西的高度和宽度,所以你应该返回一个表示某个东西的对象)或者b)这是一个代码气味,你真的需要考虑为什么该方法返回两个值(例如,该方法实际上做了两件事)。
答案 4 :(得分:3)
不直接。您可以选择返回某种自定义结构或具有多个属性的类,如果您只想返回两个值,请使用KeyValuePair,或使用out parameters。
答案 5 :(得分:3)
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
}
答案 6 :(得分:1)
你基本上(至少)有两个选项,要么除了函数的返回值之外还要创建一个out参数,比如T1 Function(out T2 second)
,或者你自己的类将这两种类型放在一起,就像这样一个Pair<T1,T2>
。我个人更喜欢第二种方式,但这是你的选择。
答案 7 :(得分:1)
在C#中,您可以使用out参数返回多个值。请参阅Int32 struct的TryParse方法中的示例。它在out参数中返回bool和一个整数。
答案 8 :(得分:1)
不,但您可以使用输出参数
int whatitis;
string stuff = DoStuff(5, out whatitis);
public string DoStuff(int inParam, out int outParam)
{
outParam = inParam + 10;
return "donestuff";
}
答案 9 :(得分:0)
除非返回包含多个值的类型(Struct,Dictionary等),否则无法从函数返回多个值。唯一的另一种方法是在传入的参数上使用“out”或“ref”关键字。
答案 10 :(得分:0)
您可以使用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
}
我真的倾向于远离这个,我认为这是一种代码味道。它适用于快速和脏。一种更可测试且更好的方法是传递代表您的域的对象(需要看到两个这两个值)。
答案 11 :(得分:0)
你可以试试这个
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
答案 12 :(得分:0)
要返回2个值,我通常使用http://blog.o-x-t.com/2007/07/16/generic-pair-net-class/中的Pair类。 如果您需要从描述范围的方法2值返回,例如从/到或最小/最大,您可以use FromToRange class。
public class FromToRange<T>
{
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<T> pair = obj as FromToRange<T>;
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);
}
}