Why is an ExpandoObject breaking code that otherwise works just fine?

前端 未结 7 952
感动是毒
感动是毒 2021-02-01 02:12

Here\'s the setup: I have an Open Source project called Massive and I\'m slinging around dynamics as a way of creating SQL on the fly, and dynamic result sets on the fly.

<
7条回答
  •  陌清茗
    陌清茗 (楼主)
    2021-02-01 02:48

    Looking at the exception being thrown, it seems that even though OpenConnection returns a static type (DbConnection) and CreateCommand returns a static type (DbCommand), because the parameter passed to DbConnection is of type dynamic it's essentially treating the following code as a dynamic binding site:

     var cmd = CreateCommand(ex);
        cmd.Connection = conn;
    

    Because of this, the runtime-binder is trying to find the most specific binding possible, which would be to cast the connection to SqlConnection. Even though the instance is technically a SqlConnection, it's statically typed as DbConnection, so that's what the binder attempts to cast from. Since there's no direct cast from DbConnection to SqlConnection, it fails.

    What seems to work, taken from this S.O. answer dealing with the underlying exception type, is to actually declare conn as dynamic, rather than using var, in which case the binder finds the SqlConnection -> SqlConnection setter and just works, like so:

    public static dynamic DynamicWeirdness()
        {
            dynamic ex = new ExpandoObject();
            ex.TableName = "Products";
            using (dynamic conn = OpenConnection())
            {
                var cmd = CreateCommand(ex);
                cmd.Connection = conn;
            }
            Console.WriteLine("It worked!");
            Console.Read();
            return null;
        }
    

    That being said, given the fact that you statically typed the return type of CreateCommand to DbConnection, one would have thought the binder would have done a better job of "doing the right thing" in this case, and this may well be a bug in the dynamic binder implementation in C#.

提交回复
热议问题