mercredi 1 juin 2016

Calling `Contains` method from C# dynamic type yields error - why?

I simplified my problem into a tiny program which examples the exact error I receive during run-time.

You can copy-paste it into a console application and see for yourself.

using System.Collections.Generic;

namespace ConsoleApplication5
{
    class Program
    {
        static void Main(string[] args)
        {
            var list = new List<MyDataClass>()
            {
                new MyDataClass {A = 1, B = 1},
                new MyDataClass {A = 3, B = 8}
            };
            var ops = new MyOperationsClass();
            ops.ReallyGreatOperation(list, list[0]);
        }
    }

    public class MyDataClass
    {
        public int A { get; set; }
        public int B { get; set; }

        public void AddDataPartsToEachOther()
        {
            var c = A + B;
            A = c;
            B = c;
        }
    }

    public class MyOperationsClass
    {
        public void ReallyGreatOperation(object obj, object z)
        {
            dynamic x = obj;
            if (x.Contains(z)) //<-- gets an error here..
                ((dynamic)z).AddDataPartsToEachOther();
        }
    }
}

So what is really the problem?

As I understand dynamic keyword can be used as a wildcard, if a method exists it will be called with no problem. so why is it not working for me in this scenario?

Now, I know that I can change it to work by doing this:

public class MyOperationsClass
{
    public void ReallyGreatOperation(object obj, object z)
    {
        dynamic x = obj;
    //    if (x.Contains(z)) //<-- gets an error here..
    //        ((dynamic)z).AddDataPartsToEachOther();
        if (x.GetType().GetMethod("Contains").Invoke(obj, new[] {z}))
            ((dynamic)z).AddDataPartsToEachOther();
    }
}

But as I said - what I wish is to understand why the more "natural" way is not working.. cause if I do it the 2nd way out of no choice - I don't see the point of dynamic in the language anymore.

The actual error received:

An unhandled exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in System.Core.dll

Additional information: The best overloaded method match for 'System.Collections.Generic.List.Contains(ConsoleApplication5.MyDataClass)' has some invalid arguments

Thanks.





Aucun commentaire:

Enregistrer un commentaire