RickStrahl / Expando

Extensible dynamic types for .NET
108 stars 30 forks source link

Indexer and property getters different values for strongly typed class after cast from dynamic #1

Closed maxshenfield closed 7 years ago

maxshenfield commented 9 years ago

Inheriting from Expando is great - but if the inheriting class implements strongly typed properties, setting a property dynamically causes some problems. If the types don't agree, casting the dynamic instance back to its static type will give different values for the property depending on whether you use the indexer or property to access it. For example

class Person : Expando
{
    public string Name {get; set;}
}

void Main()
{
    dynamic ex = new Person();
    ex.Name = 100;
    var person = ex as Person;
    Console.WriteLine(person.Name);
    //>> null
    Console.WriteLine(person ["Name"]);
    //>> 100
}
RickStrahl commented 9 years ago

Hmmm... good catch!

Not sure how this can be fixed though. The dynamic internals handle the routing. Ultimately if you use the dynamic invocations you end up responsible for the type safety.

I'll take a look.

RickStrahl commented 7 years ago

Ok I've added some logic that now throws when the assignment of type is invalid.

       [TestMethod]
        [ExpectedException(typeof(RuntimeBinderException))]
        public void InvalidAssignmentErrorOnStaticProperty()
        {
            dynamic dynUser = new User();  // has string Name
            dynUser.Name = 100;  // RuntimeBinderException

            // this should never run
            var user = dynUser as User;
            user.Name = "Rick";
            Console.WriteLine(user.Name);                        
            Console.WriteLine(user["Name"]);

            Assert.Fail("Invalid Assignment should have thrown exception");
            //>> 100
        }