4

I have a generic class Program with static method as below:

class Program
{
    public static void Main()
    {
        Console.WriteLine("HI from program");
        Console.ReadLine();
    }
}

When I try to access the static Main method inside a generic class Program1 as below:

class Program1<T> : Program where T : Program
{
    public static void check()
    {
        T.Main();                
    }
}

I get the error :

'T' is a 'type parameter', which is not valid in the given context

However if I use

public static void check()
{
    Program.Main();                
}

Everything runs fine. Can you please explain the mistake that I might be committing?

Rémi
  • 3,867
  • 5
  • 28
  • 44
ABCD
  • 249
  • 1
  • 4
  • 17
  • In this case, you can call Main() with no prefix required – stuartd May 02 '13 at 10:36
  • I know it's tempting to think of `static` as meaning "belonging to the class rather than an instance", in which case something like this should work; but a better way to think of **C#'s** `static` is "resolvable at compile-time", which makes it obvious why this doesn't. – AakashM May 02 '13 at 11:02
  • @AakashM: I don't see why the call would not be technically resolvable at compile time, so it's not immediately clear why that definition is better. – Jon May 02 '13 at 11:08
  • @jon because C# doesn't have 'virtual static', it's possible for `T` to be something without a `Main`; is the compiler supposed to check every inheritor of `Program` in order to bind the call? – AakashM May 02 '13 at 11:28
  • @AakashM: No, but it could use the knowledge of the exact type of `T` for a particular instantiation of `Program1` to bind directly to that class, a-la C++ templates. I am aware that generics don't work like that (e.g. it would not be possible to provide a generic type that does this in an assembly that I could reference in my app) so this is not doable in practice, but at the very least it is not *obvious* why this is not resolvable. What makes it non-resolvable is the fact that `Program1` is compiled independently from its eventual type argument `T`. – Jon May 02 '13 at 11:40
  • @Jon right, got you. Outside the edit window for my comment now... – AakashM May 02 '13 at 12:02

2 Answers2

3

When you do Program1 : Program, you are telling all Program1 instances are not only of type Program1, but also of type Program, because it inherits it.

But when you do Program1<T>, you are telling Program1 can have any independent type parameter in addition of it's own type, to do things with that independent type.

In case you use Program1 : Program, your static method can do the following:

class Program1 : Program
{
    public static void check()
    {
        Program.Main() // but the real good thing to do is just avoid this check method.
        // and use just Program1.Main() in other places
    }
}

In the case of using Program1<T>, I can't see anything that explains that usage, unless you are trying to do some further thing we didn't read in the question. Here, T is not really program, even if you set the constraint as you did. T is a mere generic type. The reasons to use it is to allow your class to work with different types. If you are working with only one type, there's no reason to use the generic type, just use Program.

Daniel Möller
  • 84,878
  • 18
  • 192
  • 214
2

I think you may not want "Program1" to extend "Program", when the condition for your Generic Type is to be of type "Program" itself.

sandeep
  • 149
  • 1
  • 12