gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 14:40:47 24 4
gpt4 key购买 nike

设置如下:我有一个名为 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;
}

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

现在,如果我将字符串参数更改为动态 - 特别是 ExpandoObject(假设某处有一个例程将 Expando 处理为 SQL) - 则会引发一个奇怪的错误。代码如下:

Dynamic Error

以前有效的方法现在失败了,并显示一条毫无意义的消息。 SqlConnection DbConnection - 此外,如果将鼠标悬停在调试中的代码上,您可以看到类型都是 SQL 类型。 “conn”是一个SqlConnection,“cmd”是一个SqlCommand。

这个错误完全没有意义 - 但更重要的是,它是由于 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,它就可以工作:) - 这是我的意思的图像:

enter image description here

最佳答案

当您将动态传递给 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。

关于c# - 为什么 ExpandoObject 会破坏原本可以正常工作的代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7562205/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com