I need to pass a List of Types to a method, but I want to be sure (at compile time that is) that all of them inherit from BaseType. Also, I dont know how many Types have to be passed.
So I figured this would be a bad way to go:
public void DoSomething(params Type[] types)
So what I ended up doing up to now is something like this:
private void DoSomething(params Type[] types)
public void DoSomething<T1>()
where T1 : BaseType
{
DoSomething(typeof(T1));
}
public void DoSomething<T1, T2>()
where T1 : BaseType
where T2 : BaseType
{
DoSomething(typeof(T1), typeof(T2));
}
public void DoSomething<T1, T2, T3>()
where T1 : BaseType
where T2 : BaseType
where T3 : BaseType{...}
// and so on...
You get the Idea. So the Question is: can you do this a bit more beautifully? Because this does not support an arbitrary number of types. And in my scenario, eight or more types would not be too uncommon.
I want to use this for "magic" of this kind but the caller does not have a reference to the container.
In C, there are two types of parameters and they are as follows... The actual parameters are the parameters that are speficified in calling function. The formal parameters are the parameters that are declared at called function.
Except for functions with variable-length argument lists, the number of arguments in a function call must be the same as the number of parameters in the function definition. This number can be zero. The maximum number of arguments (and corresponding parameters) is 253 for a single function.
Supported parameter types are string, integer, Boolean, and array.
Mandatory and Optional Parameters That is, when we initialise a parameter with a default value, it becomes optional. Otherwise, the parameter will be mandatory. In the above example, man1 and man2 are mandatory because they are not initialised in the function definition.
There's no way to represent such a constraint in C# (or CIL for that matter), so you're going to either have to struggle through with writing all those overloads, or give up compile-time safety and just check at run-time.
If possible, one other alternative would be to write an overload that can make use of examples. Whether or not this would be useful depends on the domain, really.
public void DoSomething(params BaseClass[] examples)
{
//null-checks here
Type[] types = examples.Select(e => e.GetType())
.ToArray();
//...
}
Usage (let's say the BaseClass
was Mammal
):
// Compiles fine.
DoSomething(new Goat(), new Tiger(), new Lion());
// Won't compile.
DoSomething(new Fish(), new Tiger(), new Lion());
And here's a sample for checking at run-time:
public void DoSomething(Type[] types)
{
//null-checks here
// Or perhaps you want IsSubclassOf...
if(types.Any(t => !typeof(BaseClass).IsAssignableFrom(t))
throw new ArgumentException(...);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With