locked
call static method from generic method RRS feed

  • Question

  • In a generic method, I want to call a static method of the class that the method is being implemented on.
    But I get an error: T is a type parameter and is not valid in the given context.

    I call a static method by specifying
      ClassName.StaticMethodName( ).

    I figure in a generic method, I should be able to call a static of the generic class:
        T.StaticMethodName( ).

    The contstraints of T are any class derived from a class name. And that base class does have the T.StaticMethodName as a static method.

    Can I call a static method from a generic method in this way?

    thanks,

      public static class StaticMethods
      {
        public static void TryParse<T>() where T : BaseClass
        {
          string s1 = DerivedClass.StaticMethod();

        // error: T is a type parameter and is not valid in the given context.
          string s2 = T.StaticMethod();
        }
      }

      public class BaseClass
      {
        public static string StaticMethod()
        {
          return "BaseClass";
        }
      }

      public class DerivedClass : BaseClass
      {
        public static new string StaticMethod()
        {
          return "DerivedClass";
        }
      }

    Thursday, February 17, 2011 3:49 PM

Answers

  •   public static class StaticMethods
      {
        public static void TryParse<T>()
        {
          string s1 = DerivedClass.StaticMethod();
          string s2 = BaseClass.StaticMethod();
        }
      }
    
      public class BaseClass
      {
        public static string StaticMethod()
        {
          return "BaseClass";
        }
      }
    
      public class DerivedClass : BaseClass
      {
        public static new string StaticMethod()
        {
          return "DerivedClass";
        }
      }
    • Marked as answer by Steve Richter Thursday, February 17, 2011 4:59 PM
    Thursday, February 17, 2011 3:57 PM
  • If I understand what you're trying to do that won't work, static methods are non-virtual.  You are hiding the static implementation of the method in the DerivedClass, but since statics are non-virtual any attempt to call BaseClass.StaticMethod will always return the BaseClass method.

    In short, you cannot override a static method definition.


    James Michael Hare

    Blog: http://www.geekswithblogs.net/BlackRabbitCoder

    Twitter: @BlkRabbitCoder

    There are 10 kinds of people in the world: those who know binary and those who don't...

    • Marked as answer by Steve Richter Thursday, February 17, 2011 4:58 PM
    Thursday, February 17, 2011 4:22 PM
  • You could try something like this :

    class Base
    {
     public static void StaticMethod()
     {
       Console.WriteLine("From Base");
     }
    
     public virtual void Foo()
     {
       StaticMethod();
     }
    }
    
    class Derived : Base
    {
     public static new void StaticMethod()
     {
       Console.WriteLine("From Derived");
     }
    
     public override void Foo()
     {
       StaticMethod();
     }
    }
    
    class Ref<T> where T : Base
    {
     public void Foo(T obj)
     {
       obj.Foo();
     }
    }
    
    class Program
    {
     static void Main(string[] args)
     {
       new Ref<Base>().Foo(new Base()); // calls Base.StaticMethod
       new Ref<Base>().Foo(new Derived()); // calls Derived.StaticMethod    
     }    
    }
    
    

    http://blog.voidnish.com
    • Marked as answer by Steve Richter Thursday, February 17, 2011 4:58 PM
    Thursday, February 17, 2011 4:39 PM
    Moderator
  • The basic problem is that you are trying to treat a static method as if it were an instance method.  You would need to encapsulate the static method call into an instance method, AND define an interface that defined the method used to wrap the static call.



            static void Main(string[] args)
            {
                Console.WriteLine(StaticMethods.TryParse<BaseClass>());
                Console.WriteLine(StaticMethods.TryParse<DerivedClass>());
                Console.ReadLine();
            }




        public interface IStaticMethod
        {
            string InvokeStaticMethod();
        }

        public static class StaticMethods
        {
            public static string TryParse<T>() where T : IStaticMethod, new()
            {
                T instance = new T();
                string s1 = instance.InvokeStaticMethod();
                return s1;
            }
        }

        public class BaseClass : IStaticMethod
        {
            public BaseClass() { }
            public static string StaticMethod()
            {
                return "BaseClass";
            }

            string IStaticMethod.InvokeStaticMethod()
            {
                return StaticMethod();
            }
        }

        public class DerivedClass : BaseClass , IStaticMethod
        {
            public DerivedClass() { }
            public new static string StaticMethod()
            {
                return "DerivedClass";
            }

            string IStaticMethod.InvokeStaticMethod()
            {
                return StaticMethod();
            }
        }

     


    Mark the best replies as answers. "Fooling computers since 1971."

    http://rudedog2.spaces.live.com/default.aspx

    • Marked as answer by Steve Richter Thursday, February 17, 2011 4:57 PM
    Thursday, February 17, 2011 4:41 PM
    Moderator

All replies

  • Call the static method on the generic constraint type, in your example that'd be BaseClass.StaticMethod (that achieves what you want).
    http://blog.voidnish.com
    Thursday, February 17, 2011 3:54 PM
    Moderator
  •   public static class StaticMethods
      {
        public static void TryParse<T>()
        {
          string s1 = DerivedClass.StaticMethod();
          string s2 = BaseClass.StaticMethod();
        }
      }
    
      public class BaseClass
      {
        public static string StaticMethod()
        {
          return "BaseClass";
        }
      }
    
      public class DerivedClass : BaseClass
      {
        public static new string StaticMethod()
        {
          return "DerivedClass";
        }
      }
    • Marked as answer by Steve Richter Thursday, February 17, 2011 4:59 PM
    Thursday, February 17, 2011 3:57 PM
  • Call the static method on the generic constraint type, in your example that'd be BaseClass.StaticMethod (that achieves what you want).
    http://blog.voidnish.com


    It is not working for me. The BaseClass static method is being called when the generic method implements the DerivedClass class.

    I changed the code so the static method returns a string. The generic method calls the static and itself returns the string returned by the static method. Then I MessageBox.Show that string.


          string rv = StaticMethods.TryParse<DerivedClass>();
          MessageBox.Show(rv);

      public static class StaticMethods
      {
        public static string TryParse<T>() where T : BaseClass
        {
          string s1 = BaseClass.StaticMethod();
          return s1;
        }
      }

      public class BaseClass
      {
        public static string StaticMethod()
        {
          return "BaseClass";
        }
      }

      public class DerivedClass : BaseClass
      {
        public new static string StaticMethod()
        {
          return "DerivedClass";
        }
      }

    Thursday, February 17, 2011 4:15 PM
  • If I understand what you're trying to do that won't work, static methods are non-virtual.  You are hiding the static implementation of the method in the DerivedClass, but since statics are non-virtual any attempt to call BaseClass.StaticMethod will always return the BaseClass method.

    In short, you cannot override a static method definition.


    James Michael Hare

    Blog: http://www.geekswithblogs.net/BlackRabbitCoder

    Twitter: @BlkRabbitCoder

    There are 10 kinds of people in the world: those who know binary and those who don't...

    • Marked as answer by Steve Richter Thursday, February 17, 2011 4:58 PM
    Thursday, February 17, 2011 4:22 PM
  • If I understand what you're trying to do that won't work, static methods are non-virtual.  You are hiding the static implementation of the method in the DerivedClass, but since statics are non-virtual any attempt to call BaseClass.StaticMethod will always return the BaseClass method.

    In short, you cannot override a static method definition.

    Thanks for the reply. I was hoping to be able to say:
       T.StaticMethod( )

    where the compiler would substitute T with the generic class.

        public static string TryParse<T>() where T : BaseClass
        {
          string s1 = T.StaticMethod();
          return s1;
        }
    Thursday, February 17, 2011 4:29 PM
  • You could try something like this :

    class Base
    {
     public static void StaticMethod()
     {
       Console.WriteLine("From Base");
     }
    
     public virtual void Foo()
     {
       StaticMethod();
     }
    }
    
    class Derived : Base
    {
     public static new void StaticMethod()
     {
       Console.WriteLine("From Derived");
     }
    
     public override void Foo()
     {
       StaticMethod();
     }
    }
    
    class Ref<T> where T : Base
    {
     public void Foo(T obj)
     {
       obj.Foo();
     }
    }
    
    class Program
    {
     static void Main(string[] args)
     {
       new Ref<Base>().Foo(new Base()); // calls Base.StaticMethod
       new Ref<Base>().Foo(new Derived()); // calls Derived.StaticMethod    
     }    
    }
    
    

    http://blog.voidnish.com
    • Marked as answer by Steve Richter Thursday, February 17, 2011 4:58 PM
    Thursday, February 17, 2011 4:39 PM
    Moderator
  • The basic problem is that you are trying to treat a static method as if it were an instance method.  You would need to encapsulate the static method call into an instance method, AND define an interface that defined the method used to wrap the static call.



            static void Main(string[] args)
            {
                Console.WriteLine(StaticMethods.TryParse<BaseClass>());
                Console.WriteLine(StaticMethods.TryParse<DerivedClass>());
                Console.ReadLine();
            }




        public interface IStaticMethod
        {
            string InvokeStaticMethod();
        }

        public static class StaticMethods
        {
            public static string TryParse<T>() where T : IStaticMethod, new()
            {
                T instance = new T();
                string s1 = instance.InvokeStaticMethod();
                return s1;
            }
        }

        public class BaseClass : IStaticMethod
        {
            public BaseClass() { }
            public static string StaticMethod()
            {
                return "BaseClass";
            }

            string IStaticMethod.InvokeStaticMethod()
            {
                return StaticMethod();
            }
        }

        public class DerivedClass : BaseClass , IStaticMethod
        {
            public DerivedClass() { }
            public new static string StaticMethod()
            {
                return "DerivedClass";
            }

            string IStaticMethod.InvokeStaticMethod()
            {
                return StaticMethod();
            }
        }

     


    Mark the best replies as answers. "Fooling computers since 1971."

    http://rudedog2.spaces.live.com/default.aspx

    • Marked as answer by Steve Richter Thursday, February 17, 2011 4:57 PM
    Thursday, February 17, 2011 4:41 PM
    Moderator