Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elegantly passing lists and objects as params

Tags:

c#

In C#, one can use the params keyword to specify an arbitrary number of typed parameters to a method:

public void DoStuff(params Foo[] foos) {...}

public void OtherStuff {
    DoStuff(foo1);
    DoStuff(foo2, foo3);
}

If you already have a list of objects, you can turn it into an array to pass to this method:

DoStuff(fooList.ToArray());

However, is there any elegant way to mix-n-match? That is, to pass in multiple objects and lists of objects and have the results flattened into one list or array for you? Ideally, I would like to be able to call my method like this:

DoStuff(fooList, foo1, foo2, anotherFooList, ...);

As of right now, the only way I know how to do this is to pre-process everything into one list, and I don't know of any way to do this generically.

Edit: To be clear, I'm not married to the params keyword, it's just a related mechanism that helped me explain what I wanted to do. I'm quite happy with any solution that looks clean and flattens everything into a single list.

like image 604
ean5533 Avatar asked Aug 05 '13 19:08

ean5533


People also ask

How do you pass objects in params?

To pass an object as an argument we write the object name as the argument while calling the function the same way we do it for other variables. Syntax: function_name(object_name); Example: In this Example there is a class which has an integer variable 'a' and a function 'add' which takes an object as argument.

What is params object in C#?

params (C# Reference) By using the params keyword, you can specify a method parameter that takes a variable number of arguments. The parameter type must be a single-dimensional array.

What is a params keyword?

params is a special keyword that allows passing a variable number of parameters into a method. It allows a nice, flexible syntax that helps us specify: One or multiple parameters separated by commas (that's the 'killer feature') No parameters at all. A single parameter of a single-dimensional array type.


1 Answers

You could create a class with implict conversions to wrap a single element and a list:

public class ParamsWrapper<T> : IEnumerable<T>
{
    private readonly IEnumerable<T> seq;

    public ParamsWrapper(IEnumerable<T> seq)
    {
        this.seq = seq;
    }

    public static implicit operator ParamsWrapper<T>(T instance)
    {
        return new ParamsWrapper<T>(new[] { instance });
    }

    public static implicit operator ParamsWrapper<T>(List<T> seq)
    {
        return new ParamsWrapper<T>(seq);
    }

    public IEnumerator<T> GetEnumerator()
    {
        return this.seq.GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }
}

then you can change your DoStuff method to:

private static void DoStuff(params ParamsWrapper<Foo>[] foos)
{
    Foo[] all = foos.SelectMany(f => f).ToArray();
    //
}
like image 141
Lee Avatar answered Oct 08 '22 05:10

Lee