C# Compiler : cannot access static method in a non-static context

前端 未结 5 637
独厮守ぢ
独厮守ぢ 2020-12-18 17:48

I have the code below :

public class Anything
{
    public int Data { get; set;}
}

public class MyGenericBase
{
    public void InstanceMethod(T da         


        
相关标签:
5条回答
  • 2020-12-18 18:19

    To call the static method you need to refer to it from the class it's defined in, not an instance of that class.

     MyGenericBase<Anything>.StaticMethod( null );
    
    0 讨论(0)
  • 2020-12-18 18:26

    You can't do this in C#. You can do it in VB.NET and Java, but honestly, it doesn't really make sense. It just gives you a false sense of polymorphism in a static method, which is not real by any means. Since it's not polymorphic, the whole method call is known at compile time (statically) and you could mention the call directly with the class name.

    0 讨论(0)
  • 2020-12-18 18:26

    You can do one of those:

    UsefulController.StaticMethod(null);  
    MyGenericBase<Anything>.StaticMethod(null);  
    

    Using the instance is not possible, as already explained by others.

    0 讨论(0)
  • 2020-12-18 18:29

    A call to a static method will be compiled to call a specific static method on a specific class. In other words, it won't use the contents of B to determine which static method to call.

    So the call has to be resolvable at compile time, hence it complains, because for all it knows, you could replace the contents of that property with multiple concrete types, which would mean that the call to the static method would have to be resolved to a static method in either of these classes.

    The compiler does not have anything like a virtual or abstract static method, so for one you can't guarantee that all of those classes have that static method. And since the call has to be resolvable at compile time, it won't work like that.

    You can, as you've noticed, call an instance method of the object, which in turn calls the static method. This does not invalidate the above rules since when the compiler compiles that instance method, which static method it will call is constant and known.

    0 讨论(0)
  • 2020-12-18 18:31

    Since it is 9 years ago, I know it is way too many years ago. I go ahead and practiced C# without caring rl implementation. I think that your post has no goal in doing inheritance, OOAD, nor encapsulation (info hiding).

    From your code to my code here.

    public class Anything
    {
        private int data, data2; //field
    
        public Anything()
        {
            data = default(int);
        }
        public int Data { get; set; }
    }
    
    public class GenericParentClass<T>
    {
        public static void StaticMethod(T data)
        {
            // do some job
        }
    
        public void InstanceMethod(T data)
        {
            // do some job
        }
    }
    
    public sealed class UsefulController<T> : GenericParentClass<T> where  T : Anything, new()
    {
        //all static public methods must be placed before all non-static public methods. [StyleCop Rule: SA1204]
        public static new void StaticMethod(T data)  //'UsefulController'.StaticMethod(Anything) hides inherited member 'GenericParentClass<Anything>.StaticMethod(Anything)'. Use the new keyword if hiding was intended.
        {
            GenericParentClass<T>.StaticMethod(data);  //'data' is a variable but used like a type //arugement type T is not assignable to parameter type 'data'.
        }
    
        public void EncapsulatedStaticMethod()
        {
            T @class = new T(); //cannot create an instance of the variable type T because it does not have the new() constraint. //T is type and @class is variable and new is an instance.
            StaticMethod(@class);  
        }
    
        public void EncapsulatedInstanceMethod(T data)
        {
            base.InstanceMethod(data);
        }
    }
    
    public class Container
    {
        public UsefulController<Anything>  B { get; set; }
    }
    
    public class Testing   
    {
        public static void Main()
        {
            Anything @var = new Anything();
            var c = new Container();
            c.B.InstanceMethod(null);   
            c.B.EncapsulatedStaticMethod();    
            c.B.EncapsulatedInstanceMethod(var);  
        }
    }
    
    0 讨论(0)
提交回复
热议问题