简体   繁体   中英

Unable to invoke base class method

Unable to invoke the method of base class,

public class MyBaseClass
{
    public void PrintTheValue(int inputValue)
    {
        Console.WriteLine(" Printed from Base class method " + inputValue);
    }
}

public class MyDerivedClass : MyBaseClass
{
    public void PrintTheValue(long inputValue)
    {
        Console.WriteLine(" Printed from Derived class method " + inputValue);
    }
}

If I try to invoke the function,

public static void Main()
{ 
    long longValue = 5;
    int intValue = 6;
    MyDerivedClass derivedObj = new MyDerivedClass();
    derivedObj.PrintTheValue(longValue);
    derivedObj.PrintTheValue(intValue);
    Console.Read();
}

Output surprises me,

Printed from Derived class method 5
Printed from Derived class method 6

Why I am unable to invoke the function of base class?
I know what is overloading and overriding and I think it should invoke base class method,
I tried explicit cast too, derivedObj.PrintTheValue((int)longValue); but same result.

I believe you have been trapped in Overloading Methods in a base class
The way .NET runtime handles this is quite interesting as it always favors the most-derived compile-time type, means it will always try to invoke the method, (which are applicable for invocation) which is closest to the class who is invoking the method.

Technical Details:
According to Overload resolution it is mentioned that

For example, the set of candidates for a method invocation does not include methods marked override (Section 7.3), and methods in a base class are not candidates if any method in a derived class is applicable (Section 7.5.5.1).

Further reading the detailed description it can be found that, .net constructs the candidate methods that are applicable for method invocation by Member lookup rules where it is clearly mentioned in Method Invocation that,

  • The set of candidate methods for the method invocation is constructed. Starting with the set of methods associated with M, which were found by a previous member lookup (Section 7.3), the set is reduced to those methods that are applicable with respect to the argument list A. The set reduction consists of applying the following rules to each method TN in the set, where T is the type in which the method N is declared:
    • If N is not applicable with respect to A (Section 7.4.2.1), then N is removed from the set.
    • If N is applicable with respect to A (Section 7.4.2.1), then all methods declared in a base type of T are removed from the set.

And And as mentioned at Applicable function member

A function member is said to be an applicable function member with respect to an argument list A when all of the following are true:

  • The number of arguments in A is identical to the number of parameters in the function member declaration.
  • For each argument in A, the parameter passing mode of the argument (that is, value, ref, or out) is identical to the parameter passing mode of the corresponding parameter, and
    ---- for a value parameter or a parameter array, an implicit conversion (Section 6.1) exists from the type of the argument to the type of the corresponding parameter, or
  • ---- for a ref or out parameter, the type of the argument is identical to the type of the corresponding parameter. After all, a ref or out parameter is an alias for the argument passed.

    The above details can be explained by simple example,

    public class VMBase
    {
        public int Add(int a, int b)
        {
            Console.WriteLine("Base class method invoked");
            return a + b;
        }
    }
    public class MyVMBase : VMBase
    {       
        public long Add(long a , long b)
        {
            Console.WriteLine("Derived class method invoked");
            return a + b;
        }    
    }
    
    public static void Main()
    {           
       MyVMBase myObj = new MyVMBase();
       int imy = 5;
       int j = 6;
       int myaddValue = myObj.Add(imy, j); //COMPILE TIME ERROR Cannot implicitly convert type 'long' to 'int'. An explicit conversion exists (are you missing a cast?) 
       long myaddValue2 = myObj.Add(imy, j);  // NO ERROR
     }  
    

    So from above methods, it can be seen that Compile Time error is reported which means it will always invoke the method of the derived class which is public long Add(long a , long b)

    @Prateek: the reason is that the derived class accept the long value which gets satisfied even for the integer value hence you get to see that the base class is never hit.

    to understand the way your code works I have made a minor modification as provided below. try it out. you will know it in and out... :)

    public class MyBaseClass
    {
        public void PrintTheValue(long inputValue)
        {
            Console.WriteLine(" Printed from Base class method " + inputValue);
        }
    }
    
    public class MyDerivedClass : MyBaseClass
    {
        public void PrintTheValue(int inputValue)
        {
            Console.WriteLine(" Printed from Derived class method " + inputValue);
        }
    }
    
     static void Main(string[] args)
        {
            long longValue = 5;
            int intValue = 6;
            MyDerivedClass derivedObj = new MyDerivedClass();
            derivedObj.PrintTheValue(longValue);
            derivedObj.PrintTheValue(intValue);
            Console.Read();
        }
    

    output would be like this..
    在此处输入图片说明

    The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

     
    粤ICP备18138465号  © 2020-2024 STACKOOM.COM