8

In C++ templates have the feature that you can pass a value as the argument to the template of a function. How can I do the same in C#?

For instance, I want to do something similar to the following:

template <unsigned n> struct Factorial {
     enum { 
        result = n * Factorial<n - 1>::result;
     };
};
template <> struct Factorial<0> {
      enum {
        result = 1;
      };
};

but in C#. How can I do this?

By the way, my actual need for them involves generating classes on demand (with a few static values changed), so the presented code is just an example.

ludo
  • 1,456
  • 2
  • 14
  • 26
  • Is this equivalent to Generic Methods? I have no idea about C++ whatsoever. – Federico Berasategui Aug 20 '13 at 00:17
  • No, templates allow values to be passed in, while generics only allow types. I'm looking for a workaround to achieve the same effect of passing values as template parameters, but in C# (where that is not allowed) – ludo Aug 20 '13 at 00:21
  • I don't see how that is useful in an Object Oriented approach. – Federico Berasategui Aug 20 '13 at 00:23
  • 1
    Can you be more specific about what classes do you want to generate and why? – Andrey Shchekin Aug 20 '13 at 00:31
  • Generating classes can be done in C#/.Net via Emit or Code Dom (links http://stackoverflow.com/questions/7769287/c-sharp-reflection-how-to-emit-a-class)... But if you specify your actual problem ("like clone Unity interface interceptors") there could be other approaches. – Alexei Levenkov Aug 20 '13 at 00:45
  • Please also provide sample that is close to what you want, because factorial probably better solved by [memoization](http://en.wikipedia.org/wiki/Memoization), or similar problems can be solved by [currying](http://blogs.msdn.com/b/ericlippert/archive/2009/06/25/mmm-curry.aspx)... – Alexei Levenkov Aug 20 '13 at 00:48

3 Answers3

6

C# generics are not like C++ templates in that way. They only work with types and not values.

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
  • @pretobomba you could just write factorial as a recursive function. – Daniel A. White Aug 20 '13 at 00:20
  • Hehehe, my actual need for them involves generating classes on demand (with a few static values changed). A recursive function works for the example I gave, but it's not a full workaround the limitations of generics. – ludo Aug 20 '13 at 00:24
  • 3
    _my actual need for them involves generating classes on demand (with a few static values changed)_ -- is it your actual problem or a solution to some other problem that can be approached differently in C#? – Andrey Shchekin Aug 20 '13 at 00:27
  • @pretobomba please elaborate on your specific question. – Daniel A. White Aug 20 '13 at 00:28
  • It is my actual problem – ludo Aug 20 '13 at 00:28
  • http://msdn.microsoft.com/en-us/library/c6cyy67b.aspx is a pretty good explanation. – kentquirk Aug 20 '13 at 00:29
  • @pretobomba: static values are shared only by instances of the same version of the generic class, not by the entire class. As such, you could use some sort of factory or initialization method to set these static values and get a similar result. Or just use regular fields and deal with the slight overhead. – siride Aug 20 '13 at 00:32
  • 1
    @DanielA.White How can one in C# achieve the same effect as passing a value to a template in C++? – ludo Aug 20 '13 at 00:32
  • Reference for what I said above: http://stackoverflow.com/questions/9647641/resharper-warns-static-field-in-generic-type – siride Aug 20 '13 at 00:34
  • @siride Could you elaborate on the factory approach? I don't quite follow that. – ludo Aug 20 '13 at 00:34
  • @pretobomba: it really depends on what you're trying to do. My idea with the factory approach was to have some other class create instances of your generic objects, and that factory could handle details like setting up static fields. – siride Aug 20 '13 at 00:40
5

but in C#. How can I do this?

By the way, my actual need for them involves generating classes on demand (with a few static values changed), so the presented code is just an example.

As Daniel explained, this is not possible via generics.

One potential alternative is to use T4 Templates. Depending on your needs, you could potentially generate your classes based off the templates at compile time, which sounds like it might meet your needs.

Community
  • 1
  • 1
Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
-1

You are trying to make the compiler do stuff that your code should do at runtime.

Yes, this is possible in C++. In C#, It is not. The equivalent of your code in C# would be:

public class Factorial
{
    public static ulong Compute(ulong n)
    {
        if (n == 0)
            return 1;
        return n * Factorial.Compute(n - 1);
    }
}

Note that, while static code is already a bad violation of the OOP principle (but sometimes necessary), using value-based templates is even worse. Your types should depend on other types, which is possible using generics. They should not depend on concrete values.

Jan Dörrenhaus
  • 6,581
  • 2
  • 34
  • 45