CodeKicks.com
Focus on Microsoft Technologies - Tutorials, Articles, Code Samples.

Wednesday, December 16, 2009

Can static methods be called using object/instance in .NET

Ans is Yes and No

 

Yes in C++, Java and VB.NET

No in C#

 

This is only compiler restriction in c#. You might see in some websites that we can break this restriction using reflection and delegates, but we can’t, according to my little research J

I shall try to explain you…

 

Following is code sample to break this rule using reflection, it seems that it is possible to call a static method using an object, p1

using System;

namespace T
{
    class Program
    {
        static void Main()
        {
            var p1 = new Person() { Name = "Smith" };
            typeof(Person).GetMethod("TestStatMethod").Invoke(p1, new object[] { });            
        }

        class Person
        {
            public string Name { get; set; }

            public static void TestStatMethod()
            {
                Console.WriteLine("Hello");
            }
        }
    }
}

but I do not think so this method is being called using p1 rather Type Name “Person”. I shall try to prove this…

look at another example…  Test2 has been inherited from Test1.

Let’s see various scenarios…

Scenario1

using System;
namespace T
{
    class Program
    {
        static void Main()
        {
            Test1 t = new Test1();
           typeof(Test2).GetMethod("Method1").Invoke(t,
                                
new object[] { });
        }
    }

    class Test1
    {
        public static void Method1()
        {
            Console.WriteLine("At test1::Method1");
        }
    }

 

    class Test2 : Test1
    {
        public static void Method1()
        {
            Console.WriteLine("At test1::Method2");
        }
    }
}

Output:

 

At test1::Method2

Scenario2

        static void Main()
        {
            Test2 t = new Test2();
           typeof(Test2).GetMethod("Method1").Invoke(t,
                                         new object[] { });
        }

 

Output:

 

At test1::Method2

 

Scenario3

        static void Main()
        {
            Test1 t = new Test2();
           typeof(Test2).GetMethod("Method1").Invoke(t,
                           
new object[] { });
        }

 

Output:

At test1::Method2

In all above scenarios output is same, that means, Reflection also not considering the object what you pass to Invoke method in case of static methods. It is always considering the type which you specify in typeof().

So, what is the use passing instance to “Invoke”. Let see below sample

using System;
namespace T
{
    class Program
    {
        static void Main()
        {
           typeof(Test2).GetMethod("Method1").
               Invoke(
null, new object[] { });

        }
    }

 

    class Test1
    {
        public static void Method1()
        {
            Console.WriteLine("At test1::Method1");
        }
    }

    class Test2 : Test1
    {
        public static void Method1()
        {
            Console.WriteLine("At test1::Method2");
        }
    }
}

 

Output is

 

At test1::Method2

 

I was able to call Invoke “Method1” of Test2 without any object.  Yes, there no wonder here as Method1 is static. So we may conclude that static methods cannot be called using instances (only in c#)

Why Microsoft has restricted it in C#?

Ans: Really there Is no use calling static methods using objects because static methods are stateless.

but still Java and C++ latest compilers allow calling static methods using instances.

Java sample

class Test
{
     public static void main(String str[])
     {
           Person p = new Person();
           System.out.println(p.GetCount());
     }
}

 

class Person
{
  public static int GetCount()
  {
     return 100;
  }
}

 

Output
        
100

Post a Comment

Anonymous said...

Person p = new Person()
p.GetType().GetMethod("TestStatMethod").Invoke(p, new object[] {} );

The idea is to get the result of the method without having to know the type.