C# generic with constant

11,783

Solution 1

The short answer is no.

It doesn't fit the way C# generics, as apposed to C++ templates, work.

The .net generics are not a language feature, they are a runtime feature. The runtime knows how to instantiate generics from special generic bytecode which is rather restricted compared to what C++ templates can describe.

Compare this with C++ templates, which basically instantiate the whole AST of the class using substituted types. It'd be possible to add AST based instantiation to the runtime, but it'd certainly be much more complex than the current generics.

Without features like value-type arrays (which only exist in unsafe code), recursive template instantiation or template specialization using such parameters wouldn't be very useful either.

Solution 2

A workaround to this limitation is to define a class which itself exposes the literal value you are interested in. For example:

public interface ILiteralInteger
{
   int Literal { get; }
}

public class LiteralInt10 : ILiteralInteger
{
   public int Literal { get { return 10; } }
}

public class MyTemplateClass< L > where L: ILiteralInteger, new( )
{
   private static ILiteralInteger MaxRows = new L( );

   public void SomeFunc( )
   {
      // use the literal value as required
      if( MaxRows.Literal ) ...
   }
}

Usage:

var myObject = new MyTemplateClass< LiteralInt10 >( );

Solution 3

C# does not support non-type generic parameters like C++ does.

C# generics are far simpler and less capable than C++ templates. MSDN has a succinct list of Differences Between C++ Templates and C# Generics.

Solution 4

C# generics are specialized at run-time, whereas C++ templates are processed at compile-time to make an entirely new type. Given this, the runtime simply doesn't have the features to process non-type parameters (it's not just a C# issue).

Share:
11,783

Related videos on Youtube

Andrew
Author by

Andrew

http://twitter.com/proglog

Updated on December 04, 2021

Comments

  • Andrew
    Andrew over 2 years

    Is there something similar to this C++ template?

    template <int A>
    class B
    {
        int f()
        {
            return A;
        }
    }
    

    I want to make every instance of B<1>, B<2>, etc (eg tuple) a different type.

  • Admin
    Admin over 13 years
    However, additional information can be "encoded" into types (by contract definition or otherwise), it's simple to see with a fixed set of discreet types (e.g. Vn : V, where Vn.Value = n for all Vn), but there is also church numerals -- not that I recommend either approach here :-)
  • Admin
    Admin over 13 years
    Not an incorrect answer, but it would be nice if it provided a link to C# generics and/or talked about generic declaration/"instantiation" vs. template instantiation.
  • James McNellis
    James McNellis over 13 years
    @pst: Sure; you can encode information into types. You can also avoid generics altogether and write lots of nongeneric classes. In any case; I added a link to the MSDN article enumerating the major differences between templates and generics.
  • Kirill Kobelev
    Kirill Kobelev almost 7 years
    Well, at runtime (JIT) .Net makes the instantiation. Instantiation is essentially duplication with modifications. I would not oppose AST to MSIL as much. Different representation of similar concepts.
  • TopchetoEU
    TopchetoEU over 2 years
    A dirty workaround, but a clever one. Unfortunately, that's the only way for now