2

Example:

Public class a<T> where T: containsStatic
{
    public void func()
    {
        T.StaticMethod();
    }

}

Is it possible? And if not is there another way to do it?

EDIT: it gives me the error: "'T' is a type parameter, which is not valid in the current context." why is that? is there a way to fix this?

Noam Simon
  • 23
  • 4

3 Answers3

1

The problem I forsee with this is how do you guarantee that T supports StaticMethod?

However if you are sure that StaticMethod will always exist on T, you can use reflection to accomplish this fairly simply:

using System.Reflection;

public void func()
{
    var staticMethod = typeof(T).GetMethod("StaticMethod", BindingFlags.Public | BindingFlags.Static);
    staticMethod.Invoke(null, null);
}
Martin
  • 16,093
  • 1
  • 29
  • 48
  • I added the condition, is there another way now? – Noam Simon Jan 01 '20 at 17:47
  • @NoamSimon If (from your example) `containsStatic` contains the static method then it will work. – Martin Jan 01 '20 at 17:48
  • _If_ you use this solution I would add error handling since you'll get a vague `NullReferenceException` if the type does not have a static method by that name, and you'll get a different exception if it has one with that name but with a different number of parameters. – D Stanley Jan 01 '20 at 17:51
  • Martin, it actually doesn't work, it gives me this error: "'T' is a type parameter, which is not valid in the current context". what is the possible problem? – Noam Simon Jan 01 '20 at 18:43
  • @NoamSimon You haven't put `func` in a class. – Martin Jan 01 '20 at 18:56
0

Assume we wave a magic wand and you can do that now. Assume a type C:

public class C
{
    public static void Foo()
    {
    }
}

How would this:

public class A<T> where T : C
{
    public void Func()
    {
        T.Foo();
    }

}

Be any different from:

public class A<T> where T : C
{
    public void Func()
    {
        C.Foo();
    }
}

It would not. It would have to be the same method being called. A static method call is generated statically (yeah, I know) when the method's code gets generated. The compiler seeing T.Foo() wouldn't possibly be able to insert any other call than C.Foo() there.

So you can't even express that in C#'s grammar, a type parameter is disallowed by the spec in such a context:

A type parameter cannot be used in a member access (Member access) or type name (Namespace and type names) to identify a static member or a nested type.

If you want to dynamically call a static method depending on T's value at runtime, refer to @Martin 's reflection solution.

V0ldek
  • 9,623
  • 1
  • 26
  • 57
0

You can call any static method, if it does not depend on the Generic Type. If you have a class like

 public class Test<T>
 {
        public static int Result => 5;
 }

You can call

 int n = Test<int>.Result;

at any place you want, and it is not important what type you actually insert, since any type will do the same

 int n = Test<string[]>.Result;

will do the very same thing.

If your function depends on T like in

    public class Test1<T>
    {
        public static void Action(T param)
        {

        }
    }

You can use

  Test1<int>.Action(8);

At any place you want.

Also inside other generic classes:

    public  class OtherClass<T> 
    {
        public void Method(T param)
        {
            Test1<T>.Action(param);
        }
    }

But most often it is possible to write a generic function in a non-generic class like

    public class Test2
    {
        public static void Action<T>(T param)
        {

        }
    }

This works at any place in the Program

   Test2.Action("string");
   Test2.Action(9);

You can put this function in any class you want, since it's static. There is no need to put this function in a generic class.

Holger
  • 2,446
  • 1
  • 14
  • 13