0

我有一个类,其中一个属性返回 a List<object>。在该列表中,我放置了一组匿名对象。

然后稍后,我有一个使用该属性的项目作为动态变量的循环。
所以我的代码如下所示:

private List<object> BookerTypes
{
    get
    {
        if (this.bookerTypes == null)
        {
            this.bookerTypes = new List<object>();

            var com = new SqlConnection(functions.ConnectionString).CreateCommand();
            com.CommandText = @"
SELECT
    BT.id
    , BT.name
FROM dbo.BookerTypes AS BT
ORDER BY BT.name ASC
";
            com.Connection.Open();
            try
            {
                using (var dr = com.ExecuteReader())
                {
                    while (dr.Read())
                    {
                        this.bookerTypes.Add(new { id = dr.GetInt32(0), name = dr.GetString(1) });
                    }
                }
            }
            finally
            {
                com.Connection.Close();
            }
        }

        return this.bookerTypes;
    }
}

[...]

    this.cblSBT.Items.Clear();
    foreach(dynamic bt in this.BookerTypes)
    {
        this.cblSBT.Items.Add(new ListItem()
        {
            Value = bt.id.ToString()
            , Text = bt.name
            , Selected = this.competition.SubscriptionTypes.Contains((int)bt.id)
        });
    }

除了明显丢失强类型之外,还有什么理由我不应该这样做?

4

2 回答 2

3

正如您所说,不这样做的主要原因是您丢失了静态类型。也有与之相关的性能成本,但它们不如这段代码在可读性和可维护性方面的显着问题重要。

如果事实证明您拼写错误或输入了错误的变量名,您就不会得到编译时检查(并且在没有代码完成支持的情况下更容易做到)。您也没有任何有效的方法可以在编译时知道List<object>给定的变量中可能存在哪些变量。追踪该列表的来源以找出可能使用的变量是一项非常重要的任务。

在这种情况下,创建一个新的命名类型而不是使用匿名类型几乎肯定值得花时间和精力。创建新课程的少量前期成本几乎总能得到回报。

于 2013-07-09T14:27:53.467 回答
1

除了已经指出的类型安全损失和其他问题之外,我觉得dynamic在这里使用是完全错误的。

的一般用例dynamic是用于使用来自外部源的数据,例如 API/COM 等。基本上是信息类型尚未明确定义的场景。在您的场景中,您可以控制您要求的数据,并且您知道期望什么类型的数据,因此我无法证明您为什么要使用它而不是从明确定义的类型安全中获得的好处模型。

使用匿名对象+动态是不明智的吗?

在您的情况下,我认为是的。

于 2013-07-09T14:48:00.540 回答