从函数返回许多列表

时间:2018-07-16 16:49:40

标签: c# design-patterns return return-type

假设我有一个函数,该函数可以填充一些如下所示的列表:

public static List<T> foo()
{
    List<T> bar = List<T>();
    List<T> buzz = List<T>();
    List<T> bazz = List<T>();
    foreach (T item in someList)  # Cannot change
    {
        if (condition1)
        {
            bar.add(item);
        }
        if (condition2)
        {
            buzz.add(item);
        }
        if (condition3)
        {
            bazz.add(item);
        }
    }
    return bar;
}

目前我只返回一个列表,但是我有兴趣返回所有列表,因为每个列表都包含必须由调用函数进行不同处理的元素。我应该在这里返回什么?我考虑过一个列表元组或一个元组列表,但是我希望还有其他设计可以更好地满足这种模式。请注意,与建议重复的问题不同,我正在寻找一种解决方案,以解决任意数量的具有名称的列表。

我无法为每个列表将迭代分解为单独的函数,实际的迭代调用的命令不是幂等的。

作为奖励,如果列表被命名,那就太好了,因此我们不会依赖它们在某些元组等中的位置,而是可以通过“ bar”,“ buzz”等来称呼它们。

4 个答案:

答案 0 :(得分:1)

您可以使用yield。在您的调用方方法中,执行以下操作:

foreach(var list in foo())
{

}

然后您的方法如下:

public static IEnumerable<List<T>> foo()
{
    List<T> bar = new List<T>();
    List<T> buzz = new List<T>();
    List<T> bazz = new List<T>();
    foreach (var item in someList)
    {
        if (condition1)
        {
            bar.Add(item);
        }
        if (condition2)
        {
            buzz.Add(item);
        }
        if (condition3)
        {
            bazz.Add(item);
        }
    }
    yield return bar;
    yield return buzz;
    yield return bazz;
}

答案 1 :(得分:1)

如果您使用的是C#7,则可以通过以下方式编写元组:

public static (List<T> bar, List<T> buzz, List<T> bazz) foo()
{
    List<T> bar = List<T>();
    List<T> buzz = List<T>();
    List<T> bazz = List<T>();
    foreach (T item in someList)  # Cannot change
    {
        if (condition1)
        {
            bar.add(item);
        }
        if (condition2)
        {
            buzz.add(item);
        }
        if (condition3)
        {
            bazz.add(item);
        }
    }
    return (bar: bar, buzz: buzz, bazz: bazz);
}

或者,您可以创建一个BarBuzzBazz类:

public class BarBuzzBazz {
     public List<T> Bar { get; }
     public List<T> Buzz { get; }
     public List<T> Bazz { get; }

     // constructor for initialising the properties
}

并返回:

 return new BarBuzzBazz(bar, buzz, bazz);

第三种方法是将列表作为参数传递并在方法中填充它们:

public static void foo(out List<T> bar, out List<T> buzz, out List<T> bazz) 
{
    bar = List<T>();
    buzz = List<T>();
    bazz = List<T>();
    foreach (T item in someList)  # Cannot change
    {
        if (condition1)
        {
            bar.add(item);
        }
        if (condition2)
        {
            buzz.add(item);
        }
        if (condition3)
        {
            bazz.add(item);
        }
    }
}

答案 2 :(得分:0)

您可以使用元组

public static Tuple<List<T>, List<T>,List<T>> Method()
{
    List<T> list1 = List<T>();
    List<T> list2 = List<T>();
    List<T> list3 = List<T>();
    return Tuple.Create(list1, list2,list3); 
}

或您的自定义类,

创建一个具有列表属性的对象并返回:

public class MyType
{
    public List<T> Prop1 { get; set; }
    public List<T> Prop2 { get; set; }
    public List<T> Prop3 { get; set; }
}

public static MyType Method()
{
    return new MyType { Prop1 = list1, Prop2 = list2 ,Prop3 = list3};
}

答案 3 :(得分:-1)

如果只有3个列表,那为什么不将这些列表传递给函数:

void Foo(ICollection<T> one, ICollection<T> two, ICollection<T> three);

如果还有更多内容,您可以使用字典:

void Foo(IDictionary<TIdent, ICollection<T>> things);

或者,按照建议,您可以使用元组

(ICollection<T> one, ICollection<T>two, ICollection<T> three) Foo();