Why does the following test fail?
[TestClass]
public class DynamicTests
{
public class ListOfIntsTotaller
{
public float Total(List<int> list) { return list.Sum(); }
}
public static class TotalFormatter
{
public static string GetTotal(IEnumerable list, dynamic listTotaller)
{
// Get a string representation of a sum
return listTotaller.Total(list).ToString();
}
}
[TestMethod]
public void TestDynamic()
{
var list = new List<int> { 1, 3 };
var totaller = new ListOfIntsTotaller();
Assert.AreEqual("4", totaller.Total(list).ToString()); // passes
Assert.AreEqual("4", TotalFormatter.GetTotal(list, totaller)); // fails
}
}
With the following error:
Test method MyTests.DynamicTests.TestDynamic threw exception:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: The best overloaded method match for
'MyTests.DynamicTests.ListOfIntsTotaller.Total(System.Collections.Generic.List<int>)'
has some invalid arguments
Shouldn’t the binder be smart enough to match list to its underlying type of List<int> and thus successfully bind to the GetTotal method?
The problem is that
listin theGetTotalmethod is not aList<int>.The dynamic call is determined based on the type of the variable that you use, not the actual type of the object that it’s pointing to. The method
Totaltakes aList<int>, not anIEnumerable.