Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Arbitrary number of type parameters in C# [duplicate]

Tags:

c#

generics

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.

like image 252
black_puppydog Avatar asked Mar 17 '11 18:03

black_puppydog


People also ask

How many types of parameters are there in C?

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.

How many parameters can a function have in C?

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.

How many types of parameter are there?

Supported parameter types are string, integer, Boolean, and array.

What are the 2 types of function parameters?

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.


1 Answers

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(...);           
}
like image 154
Ani Avatar answered Oct 18 '22 04:10

Ani