通常一个方法只能返回一个值,但是如果在某些时候,我们想要返回多个值,例如某个方法将一个浮点数分割成一个整数和一个小数返回。
C#)中,函数方法想返回多个值,通过元组、列表、数组、类、结构体和out参数实现的方法及示例代码。
1、使用元组实现返回多个值(ValueTuple和Tuple)
1) 使用ValueTuple实现
ValueTuple
命名为元组(在C#7.1中可用),优点是它最简洁,不可变且易于构造。
private (double first, double second) GetHeight() { return (1,2); } var result = GetHeight(); Console.WriteLine($"{result.first}, {result.second}"); var (first, second) = GetHeight(); Console.WriteLine($"{first}, {second}");
2) 使用Tuple实现
.NET Framework已经具有通用的Tuple
类。但是,这些类有两个主要限制。首先,Tuple类将其属性命名为Item1,Item2,依此类推。这些名称不包含语义信息。使用这些元组类型不能实现传达每个属性的含义。新的语言功能使您可以为元组中的元素声明和使用语义上有意义的名称。
public TupleViaClassicTuple() { return new Tuple (1,2); } var tuple = ViaClassicTuple(); Console.WriteLine($"{tuple.Item1}, {tuple.Item2}");
2、使用列表(list
1) 使用List列表实现
private ListGetHeight() { return new List (){1,2}; } var result = GetHeight(); Console.WriteLine($"{result[0]}, {result[1]}");
2) 使用数组实现
private double[] GetHeight() { return new double[2]{ 1,2}; } var result = GetHeight(); Console.WriteLine($"{result[0]}, {result[1]}");
3、使用类或结构体返回多个值
1) 使用类实现
public class SomeClass { public int First { get; set; } public int Second { get; set; } public SomeClass(int first, int second) { First = first; Second = second; } } public SomeClass ViaSomeClass() { return new SomeClass(1, 2); } var someClass = ViaSomeClass(); Console.WriteLine($"{someClass.First}, {someClass.Second}");
2) 使用结构体实现
public struct ClassicStruct { public int First { get; set; } public int Second { get; set; } public ClassicStruct(int first, int second) { First = first; Second = second; } } public ClassicStruct ViaClassicStruct() { return new ClassicStruct(1, 2); } var classicStruct = ViaClassicStruct(); Console.WriteLine($"{classicStruct.First}, {classicStruct.Second}");
4、使用out参数实现
参数进行的任何操作都是在自变量上进行的。就像ref
关键字一样,除了ref要求在传递变量之前先对其进行初始化。它也类似于in关键字,除了in不允许调用的方法修改参数值。要使用out
参数,方法定义和调用方法都必须显式使用out关键字。
1) 多个out参数实现
public bool ViaOutParams(out int first, out int second) { first = 1; second = 2; return someCondition; } if(ViaOutParams(out var firstInt, out var secondInt)) Console.WriteLine($"{firstInt}, {secondInt}");
2) 使用out ValueTuple实现
public bool ViaOutTuple(out (int first,int second) output) { output = (1, 2); return someCondition; } if (ViaOutTuple(out var output)) Console.WriteLine($"{output.first}, {output.second}");
用out关键字。
Demo1:
using System;
namespace test
{
class Testout
{
public int getParts(double n, out double frac)
{
int whole;
whole = (int)n;
frac = n - whole; //pass fractional小数 part back through frac
return whole; //return integer portion 返回整数部分
}
}
class Useout
{
static void Main()
{
Testout Tout = new Testout();
int i;
double f;
i = Tout.getParts(1234.56789, out f);
Console.WriteLine("整数部分:" + i);
Console.WriteLine("小数部分:{0:#.###}" , f);
Console.WriteLine("小数部分:" + f);
Console.ReadKey(); //监听键盘事件,按任意键执行退出
}
}
}
Demo2:
///
/// Ping命令检测网络是否畅通
///
/// URL数据
/// ping时连接失败个数
///
public static bool MyPing(string[] urls, out int errorCount)
{
bool isconnected = true;
System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping();
errorCount = 0;
try
{
PingReply pr;
for (int i = 0; i < urls.Length; i++)
{
pr = ping.Send(urls[i]);
if (pr.Status != IPStatus.Success)
{
isconnected = false;
errorCount++;
Debug.LogFormat("目标服务器{0}不可达,错误计数errorCount={1}", urls[i], errorCount);
}
// Console.WriteLine("Ping " + urls[i] + " " + pr.Status.ToString());
Debug.Log("Ping " + urls[i] + " " + pr.Status.ToString());
}
}
catch
{
isconnected = false;
errorCount = urls.Length;
}
//if (errorCount > 0 && errorCount < 3)
// isconn = true;
return isconnected;
}
///
/// 检测网络连接状态
///
///
//public static void CheckServeStatus(string[] urls)
public bool CheckNetStatus(string[] urls)
{
int errCount = 0;//ping时连接失败个数
//if (!LocalConnectionStatus())
//{
// Console.WriteLine("网络异常~无连接");
//}
if (!MyPing(urls, out errCount))
{
if ((double)errCount / urls.Length >= 0.3)
{
Debug.Log("网络连接异常");
return false;
//Console.WriteLine("网络异常~连接多次无响应");
}
else
{
Debug.Log("网络连接正常");
return true;
}
}
else
{
Debug.Log("网络连接正常");
return true;
//Console.WriteLine("网络正常");
}
}