为什么ExpandoObject破坏代码可以正常工作? - c#

设置如下:我有一个名为Massive的开放源代码项目,并且我在动态周围徘徊,以动态创建SQL,并动态创建动态结果集。

为了完成数据库工作,我使用了System.Data.Common和ProviderFactory的东西。这是一个很好用的示例(它是静态的,因此您可以在控制台中运行):

    static DbCommand CreateCommand(string sql) {
        return DbProviderFactories.GetFactory("System.Data.SqlClient")
                                  .CreateCommand();
    }
    static DbConnection OpenConnection() {
        return DbProviderFactories.GetFactory("System.Data.SqlClient")
                                  .CreateConnection();
    }
    public static dynamic DynamicWeirdness() {
        using (var conn = OpenConnection()) {
            var cmd = CreateCommand("SELECT * FROM Products");
            cmd.Connection = conn;
        }
        Console.WriteLine("It worked!");
        Console.Read();
        return null;
    }

运行此代码的结果是“成功了!”

现在,如果我将字符串参数更改为dynamic-特别是ExpandoObject(假设某个地方的例程将Expando转换为SQL),则会引发奇怪的错误。这是代码:

以前的工作现在失败,并显示一条毫无意义的消息。 SqlConnection是DbConnection-而且,如果将鼠标悬停在调试中的代码上,则可以看到类型都是SQL类型。 “ conn”是一个SqlConnection,“ cmd”是一个SqlCommand。

这个错误完全没有意义-但更重要的是,它是由于存在一个ExpandoObject而引起的,该ExpandoObject没有涉及任何实现代码。两种例程之间的区别是:
1-我已将CreateCommand()中的参数更改为接受“动态”而不是字符串
2-我创建了ExpandoObject并设置了属性。

变得奇怪了。

如果仅使用字符串而不是ExpandoObject-一切正常!

    //THIS WORKS
    static DbCommand CreateCommand(dynamic item) {
        return DbProviderFactories.GetFactory("System.Data.SqlClient").CreateCommand();
    }
    static DbConnection OpenConnection() {
        return DbProviderFactories.GetFactory("System.Data.SqlClient").CreateConnection();
    }
    public static dynamic DynamicWeirdness() {
        dynamic ex = new ExpandoObject();
        ex.TableName = "Products";
        using (var conn = OpenConnection()) {
            //use a string instead of the Expando
            var cmd = CreateCommand("HI THERE");
            cmd.Connection = conn;
        }
        Console.WriteLine("It worked!");
        Console.Read();
        return null;
    }

如果我将CreateCommand()的参数换成我的ExpandoObject(“ ex”),则它将使所有代码成为“动态表达式”,并在运行时进行评估。

看来,此代码的运行时评估不同于编译时评估……这没有任何意义。

**编辑:我应该在这里添加一下,如果我对所有内容进行硬编码以显式使用SqlConnection和SqlCommand,则它会起作用:)-这是我的意思的图像:

参考方案

当您将动态传递给CreateCommand时,编译器会将其返回类型视为必须在运行时解析的动态。不幸的是,您在该解析器和C#语言之间遇到了一些奇怪的问题。幸运的是,通过消除使用var强制编译器执行您期望的操作,很容易解决:

public static dynamic DynamicWeirdness() {
    dynamic ex = new ExpandoObject ();
    ex.Query = "SELECT * FROM Products";
    using (var conn = OpenConnection()) {
        DbCommand cmd = CreateCommand(ex); // <-- DON'T USE VAR
        cmd.Connection = conn;
    }
    Console.WriteLine("It worked!");
    Console.Read();
    return null;
}

这已经在Mono 2.10.5上进行了测试,但是我确定它也可以在MS上使用。

使用Nginx将动态生成的文件作为静态文件提供 - dynamic

Nginx擅长提供静态文件,因此我想知道是否可以将动态生成的文件作为静态文件提供?例如云,我们使用PHP Minify在Nginx后面的PHP-FPM上组合CSS和JS文件,并几乎像任何静态文件一样为它们提供服务,可能带有一些版本控制和缓存。因此,它的考虑和行为更像是静态文件,然后是动态文件。我知道这听起来更像是缓存,但这就是Nginx如何以最佳状态处理静态…

当回复有时是一个对象有时是一个数组时,如何在使用改造时解析JSON回复? - java

我正在使用Retrofit来获取JSON答复。这是我实施的一部分-@GET("/api/report/list") Observable<Bills> listBill(@Query("employee_id") String employeeID); 而条例草案类是-public static class…

改造正在返回一个空的响应主体 - java

我正在尝试使用Retrofit和Gson解析一些JSON。但是,我得到的响应机构是空的。当我尝试从对象中打印信息时,出现NullPointerException。我确保URL正确,并且我也确保POJO也正确。我正在使用jsonschema2pojo来帮助创建POJO类。这是我要解析的JSON{ "?xml": { "@versi…

每个文件合并后添加换行 - python

我有很多类似以下内容的JSON文件:例如。1.json{"name": "one", "description": "testDescription...", "comment": ""} test.json{"name"…

Json到php,json_decode返回NULL - php

我正在用PHP进行JSON解析器的一些API,用于存储有关遗产的信息。我在解析时遇到问题,因为它返回的是NULL值而不是数组或对象。简单的JSON代码可以很好地解析,但是可以这样:{"success":true,"totalCount":1,"data":[{"id":99694…