kdanylo
kdanylo

Reputation: 201

Overloaded method with string parameter is never called, the method with object parameter is called instead

I don't understand why method Value(string s) is never called for elements of List<string> when the list is passed into ToString<M>(List<M> list) method. Below is my test code extracted from LinqPad.

I have no problems calling a proper Value() method while iterating through lists outside of ToString<M>(List<M> list) method.

Thank you!

void Main()
{
    var list1 = new List<string>{"one","two","three"};
    var list2 = new List<object>{1,2,3};
    var list3 = new List<long>{1,2,3};
    "Strings".Dump();
    ToString<string>(list1);
    //list1.ForEach(i=> Value(i)); // proper overload of Value() is called 
    "Objects".Dump();
    ToString<object>(list2);
    //list2.ForEach(i=> Value(i));
    "Longs".Dump();
    ToString<long>(list3);
    //list3.ForEach(i=> Value(i));
}

public static string ToString<M>(List<M> list) 
{

    var sb = new StringBuilder();
    foreach(M i in list)
    {
        sb.AppendFormat("{0},", Value(i));
    }
    var str = sb.ToString();
    str.Dump();
    return str;
}


public static string Value(string s)
{
    "String".Dump();
    return "'" + s + "'";
}

// Define other methods and classes here
public static string Value(object o)
{
    "Object".Dump();
    return o.ToString();
}

Here is the output. It shows that Value(string s) is never called

Strings
Object
Object
Object
one,two,three,
Objects
Object
Object
Object
1,2,3,
Longs
Object
Object
Object
1,2,3,

Upvotes: 4

Views: 127

Answers (1)

D Stanley
D Stanley

Reputation: 152576

Because the binding to Value() within ToString<M> is done at compile-time. Since there's no constraint for M, the best overload it can find is Value(object).

In order to bind to Value(string) you'll have to either cast the parameter to string or to make i dynamic in your foreach loop:

foreach(dynamic i in list)
{
    sb.AppendFormat("{0},", Value(i));
}

That will then bind Value(i) at run-time which will then choose whether to use the string or object overload.

Upvotes: 6

Related Questions