代码之家  ›  专栏  ›  技术社区  ›  bitshift

什么集合允许我返回多个不同类型的对象

c#
  •  -2
  • bitshift  · 技术社区  · 6 年前

    我读了 C++ version of this question

    请有人解释清楚,如果可以,怎么做?

    0 回复  |  直到 6 年前
        1
  •  587
  •   Vimes L.B    5 年前

    在C#7及以上,见 this answer

    在以前的版本中,可以使用 .NET 4.0+'s Tuple :

    例如:

    public Tuple<int, int> GetMultipleValue()
    {
         return Tuple.Create(1,2);
    }
    

    Item1 Item2 作为财产。

        2
  •  380
  •   Francisco Noriega    7 年前

    现在C#7已经发布,您可以使用新的包含元组语法

    (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
    

    this link 要查看有关可以做什么的更多示例:)

        3
  •  185
  •   John Cummings    7 年前

    一。参考/输出参数

    使用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;
    }
    

    用完:

    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 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 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;
    }
    

    三。元组

    元组类

    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);
    }
    
        4
  •  74
  •   Samuel    16 年前

    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; }
    }
    
        5
  •  38
  •   Chris Doggett    16 年前

    public void Foo(int input, out int output1, out string output2, out string errors) {
        // set out parameters inside function
    }
    
        6
  •  33
  •   Kevin Hoffman    16 年前

    上一张海报是对的。不能从C方法返回多个值。但是,您有两个选择:

    • 返回包含多个成员的结构
    • 返回类的实例
    • 外面的 关键词)
    • 使用字典或键值对作为输出

    这里的利弊往往很难弄清楚。如果返回结构,请确保它很小,因为结构是值类型并在堆栈上传递。如果您返回一个类的实例,这里有一些设计模式,您可能希望使用这些模式来避免引起问题-可以修改类的成员,因为C通过引用传递对象(您没有像在VB中那样使用ByVal)。

    最后,您可以使用输出参数,但我将把它的使用限制在只有两个(比如3个或更少)参数的情况下,否则事情会变得难看和难以维护。此外,输出参数的使用可能会限制灵活性,因为每次需要向返回值中添加某些内容时,方法签名都必须更改,而返回结构或类实例时,可以添加成员而无需修改方法签名。

        7
  •  19
  •   Bugs Manjeet    7 年前

    你要么返回一个 类实例 或使用 外面的

    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
    
        8
  •  14
  •   nzrytmn    5 年前

    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");
    
        }
    
        9
  •  11
  •   Andrew Hare    16 年前

    有几种方法可以做到这一点。你可以用 ref 参数:

    int Foo(ref Bar bar) { }
    

    int 和(潜在的)修改 bar

    另一个类似的方法是使用 out 参数。一个 外面的 参数与 带有附加的编译器强制规则的参数。这个规则是如果你通过了 参数,则该函数必须在返回之前设置其值。除此之外 外面的 参数的工作方式就像

    最后一种方法(在大多数情况下是最好的方法)是创建一个同时封装两个值的类型,并允许函数返回:

    class FooBar 
    {
        public int i { get; set; }
        public Bar b { get; set; }
    }
    
    FooBar Foo(Bar bar) { }
    

    最后一种方法更简单,更容易阅读和理解。

        10
  •  11
  •   Francisco Noriega    8 年前

    不,您不能从C#(对于低于C#7的版本)中的函数返回多个值,至少在Python中不能这样做。

    您可以返回一个object类型的数组,其中包含您想要的多个值。

    private object[] DoSomething()
    {
        return new [] { 'value1', 'value2', 3 };
    }
    

    out 参数。

    private string DoSomething(out string outparam1, out int outparam2)
    {
        outparam1 = 'value2';
        outparam2 = 3;
        return 'value1';
    }
    
        11
  •  11
  •   Luis Teijon Khan    5 年前

    输出参数 但我建议 它们不使用异步方法 . 见 this 更多信息。

    (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}.");
    

    可以找到更多信息 here

        12
  •  10
  •   Reed Copsey    16 年前

    在C#4中,您将能够使用对元组的内置支持来轻松处理这个问题。

    同时,有两种选择。

    首先,可以使用ref或out参数将值赋给参数,这些值将被传递回调用例程。

    void myFunction(ref int setMe, out int youMustSetMe);
    

    第二,您可以将返回值包装成一个结构或类,并将它们作为该结构的成员传回。KeyValuePair对于2很好——对于超过2的情况,您需要一个自定义类或结构。

        13
  •  8
  •   Community CDub    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"
    

    但是,在序列化时要小心,所有这些都是语法上的甜点-在实际编译的代码中,这将是 Tupel<string, int> (作为 per the accepted answer )与 Item1 Item2 foo bar . 这意味着序列化(或反序列化)将使用这些属性名称。

    out 参数。你现在可以申报 内联,在某些情况下更适合:

    if(int.TryParse("123", out int result)) {
        // Do something with result
    }
    

    但是,大多数情况下,您将在.NET自己的库中使用它,而不是在您自己的函数中使用它。

        14
  •  7
  •   Rikin Patel    13 年前

    你可以试试这个“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);
    

    输出:

        15
  •  5
  •   Jose Basilio    16 年前

    类、结构、集合和数组可以包含多个值。输出和参考参数也可以在函数中设置。在动态语言和函数语言中,可以通过元组返回多个值,但在C#中不可以。

        16
  •  4
  •   blitzkriegz    16 年前

    主要有两种方法。 2。返回对象数组

        17
  •  4
  •   SHEKHAR SHETE    11 年前

    这是基本的 Two 方法:

    out '作为参数 4.0和次要版本也可以使用“out”。

    “out”的示例:

    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

    注: *那个 -关键字描述其实际变量位置被复制到被调用方法堆栈中的参数,在该堆栈中可以重写这些相同的位置。这意味着调用方法将访问更改的参数。

    2个) Tuple<T>

    使用返回多个数据类型值

    using System;
    
    class Program
    {
        static void Main()
        {
        // Create four-item tuple; use var implicit type.
        var tuple = new Tuple<string, string[], int, int[]>("perl",
            new string[] { "java", "c#" },
            1,
            new int[] { 2, 3 });
        // Pass tuple as argument.
        M(tuple);
        }
    
        static void M(Tuple<string, string[], int, int[]> tuple)
        {
        // Evaluate the tuple's items.
        Console.WriteLine(tuple.Item1);
        foreach (string value in tuple.Item2)
        {
            Console.WriteLine(value);
        }
        Console.WriteLine(tuple.Item3);
        foreach (int value in tuple.Item4)
        {
            Console.WriteLine(value);
        }
        }
    }
    

    输出

    perl
    java
    c#
    1
    2
    3
    

    注: . Tuple class . 它将被分配到内存中托管堆的单独位置。一旦您创建 元组 ,不能更改其值 fields . 这使得 元组 更像是 struct

        18
  •  4
  •   Prakash Pazhanisamy Mohamed Ali RACHID    6 年前
    <--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);
    

    我希望能成功。

        19
  •  3
  •   Community CDub    8 年前

    接受委托的方法可以向调用方提供多个值。这借用了我的回答 here 使用了一点 Hadas's accepted answer

    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
  •  2
  •   Roland    10 年前

    以面向对象的方式使用这样的类:

    class div
    {
        public int remainder;
    
        public int quotient(int dividend, int divisor)
        {
            remainder = ...;
            return ...;
        }
    }
    

    函数成员返回大多数调用方主要感兴趣的商。另外,它将剩余部分存储为一个数据成员,调用方随后可以很容易地访问它。

    我也在OP提到的C++问题中输入了这个解决方案。

        21
  •  2
  •   maoyang    9 年前

    this 文章中,您可以使用三个选项作为上述帖子。

    是最快的方法。

    外面的 在第二个。

    元组

    不管怎样,这取决于什么对你的场景是最好的。

        22
  •  2
  •   Niels    9 年前

    看看这个第9频道的演示 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
  •  2
  •   Sнаđошƒаӽ    8 年前

    可以使用动态对象。我认为它比元组有更好的可读性。

    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;
    }
    
        24
  •  1
  •   Dom    9 年前

    方法:

        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纳秒:

        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) 输出(1.64 ns)或参考

    ns->纳秒

    参考: multiple-return-values

        25
  •  0
  •   IMMORTAL    11 年前

    你可以试试这个

    public IEnumerable<string> Get()
     {
         return new string[] { "value1", "value2" };
     }
    
        26
  •  0
  •   Ruan    8 年前

    也可以使用OperationResult

    public 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;
    }
    
        27
  •  -8
  •   aliesTech    5 年前

    一个特别针对数组类型的快速答案返回:

    private int[] SumAndSub(int A, int B)
    {
        return new[] { A + B, A - B };
    }
    

    var results = SumAndSub(20, 5);
    int sum = results[0];
    int sub = results[1];