【问题标题】:C# methods with multiple return parameters [duplicate]具有多个返回参数的 C# 方法[重复]
【发布时间】:2011-07-30 12:11:45
【问题描述】:

c#/.net中是否需要多个返回参数?

public string, string GetFirstNameAndLastName(int id)
{
    var person = from p in People
                 where p.Id = id
                 select p;
    return(p.FirstName, p.LastName);
}

用法:

public void Main(string[] args)
{
    string firstName, lastName;
    (firstName, lastName) = GetFirstNameAndLastName(1);

    Console.WriteLine(firstName + ", " + lastName);
}

【问题讨论】:

  • 为什么需要将 firstName 和 lastName 作为单独的值返回?他们不应该在 Person 实例中表示吗? FirstName 和 LastName 是 Person 对象的属性。

标签: c# .net language-design


【解决方案1】:

您可以使用 C# 4.0 中的 Tuple 以轻量级的方式实现此目的

public Tuple<string, string> GetFirstNameAndLastName(int id)
{
   var person = from p in People
             where p.Id = id
             select p;
   return new Tuple<string, string>(p.FirstName, p.LastName);

   // OR
   // return Tuple.Create(p.FirstName, p.LastName);
}

System.Tuple 还具有与 F# 原生元组类型互操作的好处(嗯,它是 F# 的原生元组类型,恰好有 F# 特定的语法支持来声明元组和返回它们的函数)。

鉴于这里存在多种方法:System.Tuple、多个out 参数或返回具有FirstNameLastName 属性的POCO,我怀疑Anders Hejlsberg 可能不会添加对多次返回的显式支持价值观。

【讨论】:

  • @James 我相信您可以使用 Tuple.Create(p.FirstName, p.LastName) 来避免必须指定泛型参数。
  • 是的,刚刚更新以反映这一点;-)
  • @James:元组的唯一问题是获取组件的讨厌的.Item1.Item2 属性。使代码的可读性稍差。
  • ... 特别是因为它们从 1 开始计数,而不是像数组 f.e. 那样从 0 开始计数
  • System.Tuple 还具有与 F# 原生元组类型互操作的好处(嗯,它是 F# 的原生元组类型,恰好有 F# 特定的语法支持来声明元组和返回它们的函数.
【解决方案2】:

不,只使用out 参数。

public void GetFirstNameAndLastName(int id, out string first, out string last)
{
    var person = from p in People
                 where p.Id = id
                 select p;
    first = p.FirstName;
    last = p.LastName;
}

【讨论】:

  • 你的函数签名看起来很可疑
  • 我看不出其他答案的原因,这个答案似乎很明显、简单、直接。
  • @user492238:是的,在那里复制和粘贴有点忘乎所以。 :-)
【解决方案3】:

按照@James Webster 的建议,您可以使用元组,也可以使用dynamicExpandoObject

class Program
{
    static void Main(string[] args)
    {
        var d = GetUserDynamic();
        Console.WriteLine("{0}.{1}", d.FirstName, d.LastName);
    }

    private static dynamic GetUserDynamic()
    {
        dynamic d = new ExpandoObject();
        d.FirstName = "amandeep";
        d.LastName = "tur";
        return d;
    }
}

【讨论】:

  • 我喜欢这个解决方案。它简单易懂。明显的缺点是没有静态类型检查。
  • @Jonathan Parker 如果您要退货的东西很少,那么您不必太担心。
【解决方案4】:

没有。如果元素相关,则应返回更有用的数据类型,例如类。

public MyPersonClassGetFirstNameAndLastName(int id)
{
    var person = from p in People
                 where p.Id = id
                 select p;

    MyPersonClassreturnValue = new MyPersonClass;
    returnValue.FirstName = p.FirstName; 
    returnValue.LastName= p.LastName;
    return returnValue;
}

【讨论】:

    【解决方案5】:

    除了其他答案中指出的可能性之外,还有更多方法可以实现这一点:

    1. 创建自己的返回类型(类似于 Tuple 方法)并返回它的一个实例
    2. 参考参数:http://msdn.microsoft.com/en-us/library/14akc2c7%28v=vs.80%29.aspx

    【讨论】:

      【解决方案6】:

      视情况而定。在您的情况下,您可以返回整个人的记录,

      public string, string GetFirstNameAndLastName(int id)
      {
          var person = from p in People
                   where p.Id = id
                   select p;
          return person;
      }
      

      或者如果情况需要,您可以创建自己的数据类型。

      【讨论】:

        【解决方案7】:

        你可以像这样做你想做的事:

        public void GetFirstNameAndLastName(int id, out string firstName, out string lastName)
        {
            var person = from p in People
                         where p.Id = id
                         select p;
            firstName = p.FirstName;
            lastName =  p.LastName;
        }
        

        然后这样称呼它:

        public void Main(string[] args)
        {
            string firstName, lastName;
            GetFirstNameAndLastName(1, out firstName, out lastName);
        
            Console.WriteLine(firstName + ", " + lastName);
        }
        

        【讨论】:

        • 谁对此做了-1?我不是 out 参数的忠实拥护者,但我想听听反对者的意见。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-04-04
        • 2014-04-23
        • 2015-08-30
        • 1970-01-01
        • 1970-01-01
        • 2015-11-22
        • 1970-01-01
        相关资源
        最近更新 更多