none
Method Overloading with Data type as Object RRS feed

  • Question

  • Hey everyone, I am new to C# and trying to figure my way out with method overloading.

    I have two methods:

    public int multiply(int num1 int num2)
    { return num1* num2; }

    public object multiply(object num1 object num2)
    { return 1; }

    when I call the method multiply, then which method will be called ? If it is the data type Object, could you please explain why? and how could I change it that it calls the method with data type int? Similarly vice versa.

    I appreciate any and all help I can get :)

    Tuesday, February 25, 2020 9:58 AM

Answers

  • Hi LordPhyber,
    Based on your description, it will call the corresponding method according to the type of the parameters you pass in.
    And you can define methods as static methods, like the following code:

    public static int multiply(int num1,int num2)
    { return num1 * num2; }
    
    public static object multiply(object num1, object num2)
    { return 1; }

    Object is a base type of all other types and the object types can be assigned values of any other types, value types, reference types, predefined or user-defined types. As shown in the following code:

    object o1 = a;
    object o2 = 99.55;
    object o3 = 5;

    Best Regards,
    Daniel Zhang


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, February 26, 2020 7:27 AM
  • I'd like to expand on this answer to provide a little more context. At the point of compilation the compiler has to know which method to call based solely on the signature (but ignoring the return type). Therefore the compiler follows a rather elaborate set of rules but it starts with getting all methods that have a matching name. Then it tries to exactly match the compile-time types of the arguments. If it doesn't find an exact match then it starts looking for signatures that can match if it type coerces the arguments (e.g. int to a long or double). The last resort is a method accepting `object`. Since this is the base type of all types it will use this overload only if no other overload is better.

    In the first example since the compile time type of a/b is int/int it looks for an exact match. Since it finds one it uses that. If you had and overload accepting double/double instead then it would have used that because of type coercion. Only if none of the others matched would it fall back to object/object.

    In the second example since the compile time type of o1/o2 is object/object it wouldn't look at anything other than the object/object overload. It doesn't matter what the underlying type assigned to that value was (which is a runtime concept) because the compiler uses compile-time types only. 

    Note that you can get into ambiguity if you start mixing types in overloads such that the compiler will simply fail to pick one. This is pretty easy to get into. For example this is probably ambiguous (haven't tested).

    public double multiply ( int num1, double num2 ) { ... }
    public double multiply ( double num1, int num2 ) { ... }
    
    multiply(4.0, 5.0);  //double/double is not an overload and both existing overloads can be matched coercing one of the arguments.


    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by LordPhyber Monday, March 2, 2020 8:29 AM
    Thursday, February 27, 2020 3:44 PM
    Moderator

All replies


  • int a = 5;
    int b = 10;

    object o1 = a; //Boxing
    object o2 = b; //Boxing

    a = multiply(a,b); //It will call the parametrs of int
    o1 = multiply(o1,o2); //It will call the object parametrs


    Tuesday, February 25, 2020 10:30 AM
  • Hello,

    I would not create an object extension method as this can cause problems. Instead create extension methods to the object types you want to work with and in some cases a generic extension will do the trick like the Between extension.

    public static class ExtensionMethods 
    {
        public static bool Between<T>(this T actual, T lower, T upper) where T : IComparable<T>
        {
            return actual.CompareTo(lower) >= 0 && actual.CompareTo(upper) < 0;
        }
    
        public static int Multiple(this int value1, int value2) => value1 * value2;
        public static decimal Multiple(this decimal value1, decimal value2) => value1 * value2;
        public static double Multiple(this double value1, double value2) => value1 * value2;
        public static long Multiple(this long value1, long value2) => value1 * value2;
    }

    Usage

    // int extension
    Console.WriteLine(1.Multiple(2));
    // or
    int value1 = 1;
    int value2 = 2;
    int result = value1.Multiple(value2);
    
    // decimal extension
    Console.WriteLine(1.4M.Multiple(2));
    
    Console.WriteLine(3.Between(1, 5) ? "Yes" : "No");

    And if you really want to get into generics see the following for math calculations.

    https://www.codeproject.com/Articles/33617/Arithmetic-in-Generic-Classes-in-C


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange


    Tuesday, February 25, 2020 10:43 AM
    Moderator
  • Hi LordPhyber,
    Based on your description, it will call the corresponding method according to the type of the parameters you pass in.
    And you can define methods as static methods, like the following code:

    public static int multiply(int num1,int num2)
    { return num1 * num2; }
    
    public static object multiply(object num1, object num2)
    { return 1; }

    Object is a base type of all other types and the object types can be assigned values of any other types, value types, reference types, predefined or user-defined types. As shown in the following code:

    object o1 = a;
    object o2 = 99.55;
    object o3 = 5;

    Best Regards,
    Daniel Zhang


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, February 26, 2020 7:27 AM
  • Thank you everyone for all your help :)
    I really appreciate it a lot :)
    Wednesday, February 26, 2020 12:03 PM
  • As much as I'm not for this you can use dynamic,

    public class Helpers
    {
        public static T Multiple<T>(T sender1, T sender2)
        {
            dynamic item1 = sender1;
            dynamic item2 = sender2;
            return item1 * item2;
        }
        public static T Add<T>(T sender1, T sender2)
        {
            dynamic item1 = sender1;
            dynamic item2 = sender2;
            return item1 + item2;
        }
        public static T Subtract<T>(T sender1, T sender2)
        {
            dynamic item1 = sender1;
            dynamic item2 = sender2;
            return item1 - item2;
        }
    }
    object value1 = 2;
    object value2 = 2;
    
    var results = Helpers.Multiple(value1, value2);
    Console.WriteLine(results);
    
    value1 = 2.3;
    value2 = 2.5;
    results = Helpers.Multiple(value1, value2);
    Console.WriteLine(results);
    
    decimal d1 = 4.3M;
    decimal d2 = 2M;
    results = Helpers.Multiple(d1, d2);
    Console.WriteLine(results);



    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Wednesday, February 26, 2020 12:16 PM
    Moderator
  • I'd like to expand on this answer to provide a little more context. At the point of compilation the compiler has to know which method to call based solely on the signature (but ignoring the return type). Therefore the compiler follows a rather elaborate set of rules but it starts with getting all methods that have a matching name. Then it tries to exactly match the compile-time types of the arguments. If it doesn't find an exact match then it starts looking for signatures that can match if it type coerces the arguments (e.g. int to a long or double). The last resort is a method accepting `object`. Since this is the base type of all types it will use this overload only if no other overload is better.

    In the first example since the compile time type of a/b is int/int it looks for an exact match. Since it finds one it uses that. If you had and overload accepting double/double instead then it would have used that because of type coercion. Only if none of the others matched would it fall back to object/object.

    In the second example since the compile time type of o1/o2 is object/object it wouldn't look at anything other than the object/object overload. It doesn't matter what the underlying type assigned to that value was (which is a runtime concept) because the compiler uses compile-time types only. 

    Note that you can get into ambiguity if you start mixing types in overloads such that the compiler will simply fail to pick one. This is pretty easy to get into. For example this is probably ambiguous (haven't tested).

    public double multiply ( int num1, double num2 ) { ... }
    public double multiply ( double num1, int num2 ) { ... }
    
    multiply(4.0, 5.0);  //double/double is not an overload and both existing overloads can be matched coercing one of the arguments.


    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by LordPhyber Monday, March 2, 2020 8:29 AM
    Thursday, February 27, 2020 3:44 PM
    Moderator
  • Hi LordPhyber,
    Has your problem been solved? If it is resolved, we suggest that you mark it as the answer. So it can help other people who have the same problem find a solution quickly.
    Best Regards,
    Daniel Zhang


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, March 2, 2020 8:19 AM