有人可以清楚地说明它是否可以完成以及如何完成吗?
#1 楼
在C#7及更高版本中,请参见此答案。在以前的版本中,可以使用.NET 4.0+的Tuple:
例如:
public Tuple<int, int> GetMultipleValue()
{
return Tuple.Create(1,2);
}
具有两个值的小节具有
Item1
和Item2
作为属性。#2 楼
现在已经发布了C#7,您可以使用新的包含的Tuples语法(string, string, string) LookupName(long id) // tuple return type
{
... // retrieve first, middle and last from data storage
return (first, middle, last); // tuple literal
}
然后可以像这样使用:
var names = LookupName(id);
WriteLine($"found {names.Item1} {names.Item3}.");
您还可以为元素提供名称(因此它们不是“ Item1”,“ Item2”等)。您可以通过在签名或返回方法中添加名称来实现:
(string first, string middle, string last) LookupName(long id) // tuple elements have names
或
return (first: first, middle: middle, last: last); // named tuple elements in a literal
它们也可以被解构,这是一个非常不错的新功能:
(string first, string middle, string last) = LookupName(id1); // deconstructing declaration
查看此链接,以查看更多可以做的例子:)
评论
如果目标是.NET Framework 4.7或.NET Core 2.0之前的版本,则需要安装NuGet软件包。
–菲尔
18年5月3日在15:19
要获得退货,您可以执行以下操作:“ var result = LookupName(5); Console.WriteLine(result.middle)”。
–alansiqueira27
19年6月3日在13:08
(string,string,string)比将函数返回类型定义为Tuple
–金狮
6月17日22:28
#3 楼
您可以使用三种不同的方式1。 ref / out参数
使用ref:
static void Main(string[] args)
{
int a = 10;
int b = 20;
int add = 0;
int multiply = 0;
Add_Multiply(a, b, ref add, ref multiply);
Console.WriteLine(add);
Console.WriteLine(multiply);
}
private static void Add_Multiply(int a, int b, ref int add, ref int multiply)
{
add = a + b;
multiply = a * b;
}
使用out:
static void Main(string[] args)
{
int a = 10;
int b = 20;
int add;
int multiply;
Add_Multiply(a, b, out add, out multiply);
Console.WriteLine(add);
Console.WriteLine(multiply);
}
private static void Add_Multiply(int a, int b, out int add, out int multiply)
{
add = a + b;
multiply = a * b;
}
/> 2。 struct / class
使用struct:
struct Result
{
public int add;
public int multiply;
}
static void Main(string[] args)
{
int a = 10;
int b = 20;
var result = Add_Multiply(a, b);
Console.WriteLine(result.add);
Console.WriteLine(result.multiply);
}
private static Result Add_Multiply(int a, int b)
{
var result = new Result
{
add = a * b,
multiply = a + b
};
return result;
}
使用class:
class Result
{
public int add;
public int multiply;
}
static void Main(string[] args)
{
int a = 10;
int b = 20;
var result = Add_Multiply(a, b);
Console.WriteLine(result.add);
Console.WriteLine(result.multiply);
}
private static Result Add_Multiply(int a, int b)
{
var result = new Result
{
add = a * b,
multiply = a + b
};
return result;
}
> 3。元组
元组类
static void Main(string[] args)
{
int a = 10;
int b = 20;
var result = Add_Multiply(a, b);
Console.WriteLine(result.Item1);
Console.WriteLine(result.Item2);
}
private static Tuple<int, int> Add_Multiply(int a, int b)
{
var tuple = new Tuple<int, int>(a + b, a * b);
return tuple;
}
C#7元组
static void Main(string[] args)
{
int a = 10;
int b = 20;
(int a_plus_b, int a_mult_b) = Add_Multiply(a, b);
Console.WriteLine(a_plus_b);
Console.WriteLine(a_mult_b);
}
private static (int a_plus_b, int a_mult_b) Add_Multiply(int a, int b)
{
return(a + b, a * b);
}
评论
仅出于我自己的好奇心,您会说这是最快和“最佳实践”吗?
– Netferret
17年1月8日在10:12
“使用结构”的最佳示例:)
–SHEKHAR SHETE
17年7月11日在6:46
建议添加c#7语法(更多人对此表示赞成:)
– twomm
17年11月9日在9:59
对于您的信息,一个小的(不相关的)错字:在struct / class解决方案中,您混合了添加/乘法。
– Szak1
18年5月4日在15:30
我不知道C#元组语法是什么!数年后甚至学到新东西!
– jhaagsma
18-10-24在19:52
#4 楼
您无法在C#中执行此操作。您所能做的就是拥有一个out
参数或返回自己的类(如果希望它是不可变的,则返回结构)。使用参数
public int GetDay(DateTime date, out string name)
{
// ...
}
使用自定义类(或结构)
public DayOfWeek GetDay(DateTime date)
{
// ...
}
public class DayOfWeek
{
public int Day { get; set; }
public string Name { get; set; }
}
评论
在这种情况下,一种替代方法是使用结构代替类作为返回类型。如果返回值是无状态且瞬态的,则struct是更好的选择。
–迈克尔·梅多斯(Michael Meadows)
09年4月14日在15:44
这对于异步方法是不可能的。元组是要走的路。 (不过,我在同步操作中使用了参数;在这些情况下,它们确实很有用。)
– Codefun64
2015年11月1日在21:02
现在可以在C#7中实现:(int,int)Method(){return(1,2); }
–惊吓
17年9月18日在8:50
答案需要更新,最新版本的c#已经完全错误了。如果已更新,则将downvote更改为upvote。
–惠特尼乐园
17年12月15日在18:58
在遗留代码库上工作,返回自定义类对我来说是一种可靠的方法。
–布兰特
2月20日15:54
#5 楼
如果要返回多个值,则可以返回包含要返回的值的类/结构,也可以在参数上使用“ out”关键字,如下所示:public void Foo(int input, out int output1, out string output2, out string errors) {
// set out parameters inside function
}
评论
我认为使用“ out”或“ ref”不是很好,因为它可以完全由您自己的类类型的返回值代替。您看到,如果使用“ ref”,如何分配给这样的参数? (这仅取决于内部的编码方式)。如果在函数主体中,作者使用“ ref”将实例“更新”到参数,则意味着您可以在此处传递“可空”值。否则没有。所以这有点矛盾。我们有更好的方法(1.返回自己的班级,2. Turple)。
–user3230210
2014年4月23日下午6:54
#6 楼
以前的海报是正确的。您不能从C#方法返回多个值。但是,您确实有两个选择:返回包含多个成员的结构
返回类的实例
使用输出参数(使用out或ref关键字)
使用字典或键值对作为输出
这里的优缺点通常很难弄清楚。如果返回结构,请确保它很小,因为结构是值类型并在堆栈上传递。如果返回类的实例,则可能需要使用一些设计模式来避免引起问题-可以修改类的成员,因为C#通过引用传递对象(您不像在VB中那样具有ByVal )。
最后您可以使用输出参数,但是我将仅在只有几个参数(如3个或更少)的情况下使用此输出参数-否则情况将变得难看且难以维护。同样,使用输出参数可能会阻碍敏捷性,因为每次需要在返回值中添加某些内容时,方法签名都必须更改,而返回结构或类实例时,可以在不修改方法签名的情况下添加成员。 br />
从体系结构的角度,我建议不要使用键值对或字典。我发现这种编码风格需要使用该方法的代码中的“秘密知识”。它必须提前知道键的含义,值的含义,以及如果内部实施工作的开发人员更改了字典或KVP的创建方式,则它很容易在整个应用程序中创建故障级联。 br />
评论
并且,如果要返回的第二个值与第一个值是不相交的,则也可以引发Exception:就像当您要返回一种成功值或一种不成功值时一样。
–Cœur
14年6月16日在8:40
#7 楼
有很多方法;但是,如果您不想创建新的对象或结构或类似的东西,可以在C#7.0之后执行以下操作: (string firstName, string lastName) GetName(string myParameter)
{
var firstName = myParameter;
var lastName = myParameter + " something";
return (firstName, lastName);
}
void DoSomethingWithNames()
{
var (firstName, lastName) = GetName("myname");
}
评论
注意在元组之前使用的var!
–FlyingV
10月10日,0:36
#8 楼
在C#7中,有一个新的Tuple
语法:static (string foo, int bar) GetTuple()
{
return ("hello", 5);
}
您可以将其作为记录返回:
var result = GetTuple();
var foo = result.foo
// foo == "hello"
您还可以使用新的析构函数语法:
(string foo) = GetTuple();
// foo == "hello"
注意序列化,但是,这都是语法糖-在实际的编译代码中,这将是一个使用
Tuple<string, int>
和Item1
代替Item2
和foo
的bar
(根据接受的答案)。这意味着序列化(或反序列化)将改为使用这些属性名称。因此,要进行序列化,请声明一个记录类,然后返回该记录类。
C#7中的新增功能是
out
参数的改进语法。现在,您可以声明内联out
,它在某些情况下更适合:if(int.TryParse("123", out int result)) {
// Do something with result
}
但是,大多数情况下,您将在.NET自己的库中使用它,而不是在你自己的功能。
评论
请注意,根据您要定位的.Net版本,您可能需要安装Nuget包System.ValueTuple。
– Licht
17 Mar 29 '17 at 12:49
我正要如上所述回答;-)
–杰耶拉
17年4月28日在0:57
#9 楼
您可以返回类实例,也可以使用out参数。这是out参数的示例:void mymethod(out int param1, out int param2)
{
param1 = 10;
param2 = 20;
}
这样称呼:
int i, j;
mymethod(out i, out j);
// i will be 20 and j will be 10
评论
请记住,尽管那仅仅是因为您可以,但这并不意味着您应该这样做。在大多数情况下,这是.Net中的不良做法,被广泛接受。
–迈克尔·梅多斯(Michael Meadows)
09年4月14日在15:21
您能详细说明为什么这是一个不好的做法吗?
–左哈斯
13年1月28日在7:13
在C / C ++中,这是一个不好的做法。问题是“通过副作用编程”:int GetLength(char * s){int n = 0;而(s [n]!='\ 0')n ++; s [1] ='X';返回(n); } int main(){char greeting [5] = {'H','e','l','p','\ 0'}; int len = GetLength(greeting); cout << len <<“:” <<问候; //输出:5:HXlp}在C#中,您将必须编写:int len = GetLength(ref greeting)这将发出一个大警告标志:“嘿,调用此命令后问候语将不再相同”,并且很大减少错误。
– Dustin_00
2015年10月11日,下午4:54
#10 楼
有些答案建议使用out参数,但我建议
不要使用此参数,因为它们不适用于异步方法。有关更多信息,请参见
。
使用Tuple的其他答案,我也建议使用但使用C#7.0中引入的新功能。
(string, string, string) LookupName(long id) // tuple return type
{
... // retrieve first, middle and last from data storage
return (first, middle, last); // tuple literal
}
var names = LookupName(id);
WriteLine($"found {names.Item1} {names.Item3}.");
更多信息可以在这里找到。
#11 楼
有几种方法可以做到这一点。您可以使用ref
参数:int Foo(ref Bar bar) { }
这会将对函数的引用传递给函数,从而使函数可以修改调用代码堆栈中的对象。尽管从技术上讲这不是“返回”值,但它是一种使函数执行类似操作的方法。在上面的代码中,该函数将返回
int
并(可能)修改bar
。另一种类似的方法是使用out
参数。 out
参数与带有附加的编译器强制规则的ref
参数相同。此规则是,如果将out
参数传递给函数,则要求该函数在返回之前设置其值。除该规则外,out
参数的工作原理与ref
参数相同。 最终的方法(在大多数情况下是最好的方法)是创建一个封装两个值的类型,并允许函数返回该类型:
class FooBar
{
public int i { get; set; }
public Bar b { get; set; }
}
FooBar Foo(Bar bar) { }
最后一种方法更简单易读和理解。
#12 楼
不,您不能从C#(对于低于C#7的版本)中的函数返回多个值,至少不能以在Python中实现的方式来返回。但是有两个替代方法:
您可以返回类型对象的数组,其中包含所需的多个值。
private object[] DoSomething()
{
return new [] { 'value1', 'value2', 3 };
}
可以使用
out
参数。 private string DoSomething(out string outparam1, out int outparam2)
{
outparam1 = 'value2';
outparam2 = 3;
return 'value1';
}
#13 楼
在C#4中,您将能够使用对元组的内置支持轻松处理此问题。同时,有两种选择。
首先,您可以使用ref或out参数为您的参数分配值,这些值将传递回调用例程。
这看起来像:
void myFunction(ref int setMe, out int youMustSetMe);
其次,您可以将返回值包装到一个结构或类中,并将它们作为该结构的成员传递回去。 KeyValuePair对于2效果很好-超过2个,您将需要自定义类或结构。
#14 楼
您可以尝试使用此“ KeyValuePair”private KeyValuePair<int, int> GetNumbers()
{
return new KeyValuePair<int, int>(1, 2);
}
var numbers = GetNumbers();
Console.WriteLine("Output : {0}, {1}",numbers.Key, numbers.Value);
输出:
输出:1,2
#15 楼
<--Return more statements like this you can -->
public (int,string,etc) Sample( int a, int b)
{
//your code;
return (a,b);
}
您可以收到类似
的代码
(c,d,etc) = Sample( 1,2);
我希望它能起作用。
#16 楼
类,结构,集合和数组可以包含多个值。输出和参考参数也可以在功能中设置。通过元组,可以在动态和功能语言中返回多个值,但在C#中则不能。#17 楼
主要有两种方法。1。使用out / ref参数
2。返回对象数组
评论
还有元组和多个返回值作为元组的语法糖。
– ANeves认为SE是邪恶的
18年1月4日在17:19
#18 楼
以下是基本的Two
方法:1)使用'
out
'作为参数您也可以将'out'用于4.0和次要版本。
示例的输出:
using System;
namespace out_parameter
{
class Program
{
//Accept two input parameter and returns two out value
public static void rect(int len, int width, out int area, out int perimeter)
{
area = len * width;
perimeter = 2 * (len + width);
}
static void Main(string[] args)
{
int area, perimeter;
// passing two parameter and getting two returning value
Program.rect(5, 4, out area, out perimeter);
Console.WriteLine("Area of Rectangle is {0}\t",area);
Console.WriteLine("Perimeter of Rectangle is {0}\t", perimeter);
Console.ReadLine();
}
}
}
输出:
矩形的面积是20
矩形的周长是18
*注:*
out
-关键字描述了参数,这些参数的实际变量位置被复制到被调用方法的堆栈中,这些位置可以被重写。这意味着调用方法将访问更改的参数。2)
Tuple<T>
元组的示例:
使用
Tuple<T>
返回多个DataType值<注意:在Framework 4.0及更高版本中,使用元组是有效的。 Tuple
类型是class
。它将被分配在内存中托管堆上的单独位置。一旦创建了Tuple
,就无法更改其fields
的值。这使Tuple
更像是struct
。#19 楼
接受委托的方法可以为调用者提供多个值。这是从我在这里的答案中借来的,并使用了哈达斯公认的答案。delegate void ValuesDelegate(int upVotes, int comments);
void GetMultipleValues(ValuesDelegate callback)
{
callback(1, 2);
}
调用者提供一个lambda(或命名函数),而intellisense通过复制变量来提供帮助代表的名字。
GetMultipleValues((upVotes, comments) =>
{
Console.WriteLine($"This post has {upVotes} Up Votes and {comments} Comments.");
});
#20 楼
在本文中,您可以使用上面所述的三个选项。KeyValuePair是最快的方法。第二个是
。
元组是最慢的。
无论如何,这取决于哪种情况最适合您的情况。
#21 楼
只需以OOP方式使用这样的类即可:class div
{
public int remainder;
public int quotient(int dividend, int divisor)
{
remainder = ...;
return ...;
}
}
该函数成员返回大多数调用者主要感兴趣的商。此外,它将余数存储为数据成员。 ,之后调用者可以轻松访问。
这样,您可以拥有许多其他的“返回值”,如果您实现数据库或网络调用(可能需要很多错误消息,但仅此而已),则非常有用万一发生错误。
我也在OP所指的C ++问题中也输入了此解决方案。
#22 楼
C#的未来版本将包含命名元组。在此channel9会话上观看该演示
https://channel9.msdn.com/Events/Build/2016/B889
跳至13:00,查看元组内容。这将允许以下内容:
(int sum, int count) Tally(IEnumerable<int> list)
{
// calculate stuff here
return (0,0)
}
int resultsum = Tally(numbers).sum
(视频中的不完整示例)
#23 楼
您可以使用动态对象。我认为它比Tuple具有更好的可读性。static void Main(string[] args){
var obj = GetMultipleValues();
Console.WriteLine(obj.Id);
Console.WriteLine(obj.Name);
}
private static dynamic GetMultipleValues() {
dynamic temp = new System.Dynamic.ExpandoObject();
temp.Id = 123;
temp.Name = "Lorem Ipsum";
return temp;
}
评论
您会丢失编译时类型检查。
– Micha Wiedenmann
16 Dec 5'在13:11
#24 楼
做到这一点的方法:1)KeyValuePair(最佳性能-0.32 ns):
KeyValuePair<int, int> Location(int p_1, int p_2, int p_3, int p_4)
{
return new KeyValuePair<int,int>(p_2 - p_1, p_4-p_3);
}
2)元组-5.40 ns:
Tuple<int, int> Location(int p_1, int p_2, int p_3, int p_4)
{
return new Tuple<int, int>(p_2 - p_1, p_4-p_3);
}
3)out(1.64 ns)或ref
4)创建自己的自定义类/结构
纳秒
参考:多个返回值。
#25 楼
您可以尝试这个public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
评论
这实际上并没有返回多个值。它返回一个集合值。
–马修·豪根(Matthew Haugen)
2014年9月5日下午4:16
另外,为什么不使用yield return“ value1”;收益回报率“ value2”;不必显式创建新的字符串[]?
–托马斯·弗林科(Thomas Flinkow)
19年1月18日在6:49
#26 楼
您还可以使用OperationResultpublic OperationResult DoesSomething(int number1, int number2)
{
// Your Code
var returnValue1 = "return Value 1";
var returnValue2 = "return Value 2";
var operationResult = new OperationResult(returnValue1, returnValue2);
return operationResult;
}
评论
如果代替Item1,Item2等可以使用命名的输出值,那将是非常好的。 C#7可能会提供这一点。
–Sнаđошƒаӽ
16-09-23在8:53
@Sнаđошƒаӽ是完全正确的,预计将在即将使用的C#7.0中使用以下语法支持:public(int sum,int count)GetMultipleValues(){return(1、2); }此示例摘自与此有关的文档主题示例。
–杰普·斯蒂格·尼尔森(Jeppe Stig Nielsen)
17年1月5日,11:26
如何捕获返回的元组并在调用方访问它们?
–mLstudent33
7月11日17:35