What is the best way to return two lists in C#?

2019-02-06 01:20发布

I am almost embarrassed to ask this question, but as a long time C programmer I feel that perhaps I am not aware of the best way to do this in C#.

I have a member function that I need to return two lists of a custom type (List<MyType>) and I know beforehand that I will always have a return value of only two of these lists.

The obvious options are :

public List<List<MyType>> ReturnTwoLists();

or

public void ReturnTwoLists(ref List<MyType> listOne, ref List<myType> listTwo);

Both seem to be non-optimal.

Any suggestions on how to improve this?

The first way doesn't make it clear in the syntax that only 2 lists are being returned, and the second uses references rather then a return value, which seem so non-c#.

5条回答
放我归山
2楼-- · 2019-02-06 01:23

You have a few options:

use a Pair if the lists are meaningless in order:

 public Pair<List<MyType>,List<MyType> ReturnTwoLists()
 {
        return new Pair(new List<MyType(), new List<MyType());
 }

You can use out or ref parameters, as you mentioned. This is a good option if one list is more meaningful than the other.

You could use a dictionary if the client will know the keys, or wants to do the work to look them up:

 public Dictionary<string,List<MyType> ReturnTwoLists()
 {
        Dictionary<string,List<MyTpe>> d = new Dictionary<string,List<MyType>>();
        d.Add("FirstList",new List<MyType>());
        d.Add("SecondList",new List<MyType>());
        return new Dictionary()(new List<MyType(), new List<MyType());
 }

Or, the most "correct" solution in my eyes, for completeness and consistency, would be to create a simple data container class to hold the two lists. This provides a consumer with strongly-typed, good statically compiled (read: intellisense-enabled) return values to work with. The class can be nested right next to the method.

查看更多
时光不老,我们不散
3楼-- · 2019-02-06 01:23

Create a simple Structure that holds both and return that as the output of the function?

查看更多
别忘想泡老子
4楼-- · 2019-02-06 01:39

Your first suggestion isn't two lists. It's a list of lists.

The second option would do what you intend, but you might want to change it to use the out keyword instead of ref so the callers of your method will know the intention of what you're doing.

public void ReturnTwoLists(out List<MyType> listOne, out List<myType> listTwo);
查看更多
做自己的国王
5楼-- · 2019-02-06 01:43

Return this:

public class MyTwoLists {
    public List<MyType> ListOne {get;set;}
    public List<MyType> ListTwo {get;set;}
}
查看更多
疯言疯语
6楼-- · 2019-02-06 01:48

First of all, that should probably be out, not ref.

Second, you can declare and return a type containing the two lists.

Third, you can declare a generic Tuple and return an instance of that:

class Tuple<T,U> {
   public Tuple(T first, U second) { 
       First = first;
       Second = second;
   }
   public T First { get; private set; }
   public U Second { get; private set; }
}

static class Tuple {
   // The following method is declared to take advantage of
   // compiler type inference features and let us not specify
   // the type parameters manually.
   public static Tuple<T,U> Create<T,U>(T first, U second) {
        return new Tuple<T,U>(first, second);
   }
}

return Tuple.Create(firstList, secondList);

You can extend this idea for different number of items.

查看更多
登录 后发表回答