C # generics: any way to refer to generic parameter types as a collection?

I need to write a bunch of methods that accept parameters of type 1..N, for example:

int Foo<T1>(); int Foo<T1,T2>(); int Foo<T1,T2,T3>(); ... int Foo<T1,T2,T3...TN>(); 

Inside Foo() I would like to do something for each type, like

 int Foo<T1,T2,T3>() { this.data = new byte[3]; // allocate 1 array slot per type } 

Is there a way to parameterize this so that I don't edit all the Foo() variants, something similar to:

 int Foo<T1,T2,T3>() { this.data = new byte[_NUMBER_OF_GENERIC_PARAMETERS]; } 

Ideally, I would also like to get an array or a collection of types:

 int Foo<T1,T2,T3>() { this.data = new byte[_NUMBER_OF_GENERIC_PARAMETERS]; // can do this Type [] types = new Type[] { T1, T2, T3 }; // but would rather do this Type [] types = _ARRAY_OR_COLLECTION_OF_THE_GENERIC_PARAMETERS; } 
+7
generics c #
source share
4 answers

You can read the current general parameters and their number from the MethodInfo.GetGenericArguments array.

You can get MethodInfo for your current method using MethodBase.GetCurrentMethod .

Note that you will still need to provide some common overloads of your method with different numbers of common parameters, since C # and CLI do not support variable parameter lists.

So, your sample code for a method with three generic parameters can be written as follows:

 int Foo<T1,T2,T3>() { MethodInfo mInfo = (MethodInfo)MethodBase.GetCurrentMethod(); Type[] types = mInfo.GetGenericArguments(); this.data = new byte[types.Length]; } 
+8
source share

1) You can get the number of template arguments through reflection: http://msdn.microsoft.com/en-us/library/system.reflection.methodbase.getcurrentmethod.aspx . This way you can have a common implementation for each Foo. In each Foo, you can simply call:

 FooImpl(); 

The only difference (regarding the "GetCurrentMethod") is that you need to get information about the method of the previous method:

 StackTrace stackTrace = new StackTrace(); MethodBase methodBase = stackTrace.GetFrame(1).GetMethod(); 

2) You can generate all versions of Foo at run time - everyone will have the same call implementation only of FooImpl. Some information about the methods of generating at runtime: Dynamically creating a function at runtime, and here: <a2>

+2
source share

The .NET framework considers a general class or method with parameters of type N as having a different name from one that has more or less. Perhaps this would be possible without huge changes in the structure for organizing things in order to call a function

 foo<T>(autogeneric ref T it) 

as:

 foo(1, "George", 5.7); 

will be translated as:

 struct foo99 {public int p1; public string p2; public double p3}; ... foo99 temp99; temp99.p1 = 1; temp99.p2 = "George"; temp99.p3 = 5.7; foo1(ref temp); 

This will allow the universal method to effectively accept an arbitrary number of parameters. The ability to pass such an anonymous structure by reference may not seem very useful, but it can be very powerful when combined with lambdas.

Typically, closing local variables in a lambda expression requires lifting local variables into the heap object and building a delegate that targets that heap object. If you could use the style described above, instead of creating a permanent closure object and a delegate and passing the delegate, you could simply raise the corresponding variables into the structure and pass it byref along with the static delegate. This will only work if the called routine does not need to save a closed close, but on the other hand, the caller may know that the called procedure will not continue to close. In addition, although .NET languages โ€‹โ€‹would not support such a thing, some structural changes might be required to allow code that made it unstable by passing a structure by reference, some of which were also byrefs, that could provide lambda access ref placement procedures are something that is currently not possible (since there is no guarantee that the created delegate did not survive the area in which it was created). Structures die when the area in which they are located dies, so the problem should not exist with them.

I want .NET languages โ€‹โ€‹to have a convenient way of expressing these concepts. The fact that closures can cause the lifetimes of variables to be arbitrarily stored means that code that has ever used a variable in closures should assume that external code can change it at any time. A structural approach will not have this problem.

+1
source share

Not. You cannot use the Type parameter as you wish. But you can use something like Tuple . This allows you to exchange generics. But you cannot use TypeParamter itself.

0
source share

All Articles