Reputation: 2275
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
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
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