Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从一个方法返回两个值的最佳方法是什么?_C#_Methods_Return Value - Fatal编程技术网

C# 从一个方法返回两个值的最佳方法是什么?

C# 从一个方法返回两个值的最佳方法是什么?,c#,methods,return-value,C#,Methods,Return Value,当我必须编写返回两个值的方法时,我通常会像下面返回列表的代码那样进行操作。或者,如果我必须返回例如id和字符串,那么我将返回一个列表,然后用索引编号将其挑选出来,并重新生成值 这种按索引重铸和引用的方法似乎不雅观,因此我想为返回两个值的方法培养一种新习惯。最好的图案是什么? using System; using System.Collections.Generic; using System.Linq; namespace MultipleReturns { class Progra

当我必须编写返回两个值的方法时,我通常会像下面返回
列表的代码那样进行操作。或者,如果我必须返回例如id和字符串,那么我将返回一个
列表
,然后用索引编号将其挑选出来,并重新生成值

这种按索引重铸和引用的方法似乎不雅观,因此我想为返回两个值的方法培养一种新习惯。最好的图案是什么?

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


这比强制转换对象列表的特定元素要好得多。

模板
对如何?当然,如果传递相同的数据类型,您可以为此构造自定义数据类型,但它不是通用的


(或者C#是否允许您动态生成类?更新:ok忽略此位)

您可以返回a,从4.0开始。

为什么不
公共静态void GetIdCodeAndFileName(字符串行、字符串扩展名、输出字符串id、输出字符串文件名)

我更喜欢创建一个具有两个属性的轻量级类(见下文),或者使用元组(现在可以在.NET4的框架中使用,但不难自己编写)


在C#中返回两个值并不是一种优雅的方式。虽然我肯定认为使用
out
参数比返回
列表
要好,但这不是很容易维护或可读的。C#开发人员希望
out
,它直接受到语言的支持,而且它的功能也很好理解


从4.0开始,您可以改用元组。

我要么使用out参数,要么创建一个带有属性的结构(用于属性初始值设定项语法)并返回它。创建自定义结构/类的优点是变量命名可以匹配传递的数据。这使代码更具可读性

IdAndString GetIDAndString()
{
    return new IdAndString()
    {
        ID = 1,
        Str = "123"
    };
}

struct IdAndString
{
    public int ID { get; set; }
    public string Str { get; set; } 
}

另一个选项是返回一个
KeyValuePair

我建议使用一个轻量对象,如Mark Suggered。但也有其他模式


另一个简单的方法是,使用“按引用调用”属性。例如,调用方发送一个空数组作为参数,该参数将由函数填充。

如何将结果整齐地传递到另一个方法调用?@John:无论如何,文件名应该是任何后续方法调用的单独参数。这与e在这个例子中,问题不是更一般吗?如何将结果整齐地传递到另一个方法调用中?
inta;Foo(out a);Bar(a)
简而言之,您不需要。
out
并不优雅,但有时是必要的。@约翰:文件名应该是任何后续方法调用的单独参数。这与其他方法一样简洁。谢谢,马特。更复杂的示例是
int a;int b=Foo(out a);Bar(a,b)
如果你想要紧凑的函数式代码,请使用F#。正如我们所发现的,使用out是更干净的代码。我们过去使用结构或类来传递返回变量,结果是一团糟,因为我们有所有这些只使用过一次的类。事实证明,使用out看起来和功能都更干净。是的可以动态生成一个类,但它必须保留在本地范围内,因此它不能作为方法的返回值。@tehMick不太清楚为什么要自己删除这些标记?它们似乎与我有关。不要忘记最好的解决方案:重构代码,使每个方法在逻辑上都返回一件事。事实上,你有一个meth返回两个结果的od是一个红旗,表示该方法可能从重构中受益。使此社区wiki成为意外事件吗?您不会为CW帖子累积rep!
class MyReturnValue
{
    public string Id { get; set; }
    public string Name { get; set; }
}
IdAndString GetIDAndString()
{
    return new IdAndString()
    {
        ID = 1,
        Str = "123"
    };
}

struct IdAndString
{
    public int ID { get; set; }
    public string Str { get; set; } 
}