13

Is there a syntax trick to get to the constant in a generic class without specifying an (ad-hoc) type?

public class MyClass<T>{
    public const string MyConstant = "fortytwo";
}

// I try to avoid this type specification.
var doeswork = MyClass<object>.MyConstant;  

// Syntax similar to what I'd like to accomplish.
var doesnotwork = MyClass.MyConstant;  

There is a caveat about the static variable (constant) not being shared between different types like MyClass<object> and MyClass<int> but my question is about possible available syntax trick.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
LosManos
  • 7,195
  • 6
  • 56
  • 107
  • 2
    You could create a non-generic class `MyClass` for the constant. – Dirk Jan 08 '15 at 14:07
  • 1
    WARNING: Using `const` in public classes can cause headaches **if** the assembly is going to be referenced in another program or assembly. Use `readonly` instead. – B0Andrew Jan 08 '15 at 14:35
  • 3
    Here's a [reference](http://www.stum.de/2009/01/14/const-strings-a-very-convenient-way-to-shoot-yourself-in-the-foot/) for @B0Andrew's warning – stuartd Jan 08 '15 at 16:41

2 Answers2

16

Use a non-generic abstract parent class.

public abstract class MyClass
{
   public const string MyConstant = "fortytwo";
}

public class MyClass<T> : MyClass
{
   // stuff
}

var doeswork = MyClass.MyConstant; 

That of course assumes that there's some reason the constant needs to be part of the generic class; if it has public accessibility, I'm not seeing a reason why you wouldn't just put it in a separate class.

Having a non-generic abstract parent class is a good idea for every generic class you make; the generic class is actually a template for the specific subtype classes, rather than a true parent, so having a true non-generic parent can make some techniques (such as, but certainly not limited to, this one) a lot easier.

Oblivious Sage
  • 3,326
  • 6
  • 37
  • 58
6

Something like this works:

using System;

namespace Demo
{
    public class MyClass // Use a non-generic base class for the non-generic bits.
    {
        public const string MyConstant = "fortytwo";

        public static string MyString()
        {
            return MyConstant;
        }
    }

    public class MyClass<T>: MyClass // Derive the generic class
    {                                // from the non-generic one.
        public void Test(T item)
        {
            Console.WriteLine(MyConstant);
            Console.WriteLine(item);
        }
    }

    public static class Program
    {
        private static void Main()
        {
            Console.WriteLine(MyClass.MyConstant);
            Console.WriteLine(MyClass.MyString());
        }
    }
}

This approach works for any static types or values that you want to provide which do not depend on the type parameter. It also works with static methods too.

(Note: If you don't want anybody to instantiate the base class, make it abstract.)

Matthew Watson
  • 104,400
  • 10
  • 158
  • 276