Arbitrary number of type parameters in C #

I need to pass a list of types to a method, but I want to make sure (at compile time) that they all inherit from BaseType. Also, I don't know how many types need to be passed.

So, I decided that this would be a bad way:

public void DoSomething(params Type[] types) 

So what I have been doing so far 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 make it a little prettier? Because it does not support an arbitrary number of types. And in my scenario, eight or more types would not be too unusual.

I want to use this to β€œmagic” it , but the caller has no reference to the container.

+6
generics c #
source share
2 answers

There is no way to present such a restriction in C # (or CIL, for that matter), so you will either have to struggle to write down all these overloads, or give up security during compilation and just check -time when running.

If possible, another alternative would be to write an overload that can use examples. Regardless of whether it really will be useful, it depends on the domain, really.

 public void DoSomething(params BaseClass[] examples) { //null-checks here Type[] types = examples.Select(e => e.GetType()) .ToArray(); //... } 

Usage (say BaseClass was Mammal ):

 // Compiles fine. DoSomething(new Goat(), new Tiger(), new Lion()); // Won't compile. DoSomething(new Fish(), new Tiger(), new Lion()); 

And here is a sample to check at runtime:

 public void DoSomething(Type[] types) { //null-checks here // Or perhaps you want IsSubclassOf... if(types.Any(t => !typeof(BaseClass).IsAssignableFrom(t)) throw new ArgumentException(...); } 
+6
source share

No, a generic type is defined by a namespace, a class name, and the number of type parameters (i.e., you cannot have a class with the same name in the same namespace with the same number of type parameters, even if the restrictions on them are different).

If one class had the number of parameters of type undefined, then the structure would use this with the classes Action <> and Func <>, which is not so.

+1
source share

All Articles