Philipp Eger
Philipp Eger

Reputation: 2275

Dynamic length of generic parameters

I've written a method that gets an array of objects, the types of the array contents as generics and tries to cast each type to the delivered generic:

    public static void GetMultipleObjectsFromParameters<T, U>(
        object parameterArray, out T parameter1, out U parameter2)
    {
        parameter1 = default(T);
        parameter2 = default(U);

        try
        {
            object[] arr = parameterArray as object[];

            if (arr == null)
            {
                Debug.WriteLine("array not valid");
                return;
            }
            if (arr.Length != 2)
            {
                Debug.WriteLine("arr.Length != 2");
                return;
            }

            parameter1 = (T)arr[0];
            parameter2 = (U)arr[1];
        }
        catch (Exception ex)
        {
            Debug.Write(ex);
        }
    }

I thought this method could be very useful if I use a BackgroundWorker and want to deliver more than one argument of different types (e.g. first parameter as string, second as integer...).

Now I've just wondered if there is a way to write this method without forcing a fixed size of parameters. This would prevent me from writing a method like this for each count of parameters.

I hope the question was comprehensible. Is there an easy approach? Thank you for your help.

Upvotes: 1

Views: 529

Answers (2)

Jon Skeet
Jon Skeet

Reputation: 1503924

EDIT: This answer addresses the original question rather than the motivation behind it. In terms of passing work to a BackgroundWorker etc, using a lambda expression makes perfect sense.

Now I've just wondered if there is a way to write this method without forcing a fixed size of parameters.

Nope, I'm afraid not. What you're looking for is higher order types, I think1 - but they don't exist in .NET (which is why there are so many "generic arity overloads" for Func<>, Tuple<>, Action<> etc).


1 I don't know much about these things myself, to be honest. Joe Duffy has a blog post which blows my mind somewhat, but which may be useful.

Upvotes: 5

Dennis
Dennis

Reputation: 37800

if there is a way to write this method without forcing a fixed size of parameters

You don't need to write this method with variable size of parameters. You need Tuple:

        var myParams = Tuple.Create(100, "Hello, world!");
        var worker = new BackgroundWorker();

        worker.DoWork += (sender, args) =>
        {
            var arg = (Tuple<int, string>)args.Argument;
            if (arg.Item2.Length > 5)
            {
                var foo = arg.Item1 + 200;
            }

            // etc ...
        };

        worker.RunWorkerAsync(myParams);

or lambdas with closures:

        var someIntParam = 100;
        var someStringParam = "Hello, world!";

        var worker = new BackgroundWorker();
        worker.DoWork += (sender, args) =>
        {
            if (someStringParam.Length > 5)
            {
                var foo = someIntParam + 200;
            }

            // etc ...
        };

        worker.RunWorkerAsync();

It depends on how do you use BackgroundWorker in your real code.

Upvotes: 2

Related Questions