【问题标题】:Using Collection Initializer with System.Data.DataTable.Rows将 Collection Initializer 与 System.Data.DataTable.Rows 一起使用
【发布时间】:2014-03-28 15:23:08
【问题描述】:

据我了解,集合初始化器的使用取决于两件事:

  • 集合实现 IEnumerable
  • Add() 方法

据我所知,System.Data.DataTable.Rows 满足这两个要求,因此我希望我可以这样做:

DataRow row = _dt.Tables["TABLE"].NewRow();

_dt.Tables["TABLE"].Rows =
{
    row
};

编译器抱怨:

  • Rows 没有设置器(但我没有创建新集合,只是通过提供的引用添加到现有集合

也许你可以指出我的错误。

更新:

我刚刚意识到我的问题在于DataRowCollection,它没有实现IEnumerable,但确实有一个Add() 方法。因此,我认为这纯粹是因为 IEnumerable 没有实现,这是否正确?如果是,为什么不能添加到 BCL 中?

更新:

请参阅此代码,该代码显示您可以使用初始化程序添加到现有集合:

        public class Person
        {
            public Person()
            {
                friends.Add("Paul");
            }

            List<string> friends = new List<string>();

            public List<string> Friends
            {
                get { return friends; }
            }
        }

        Person tom = new Person
        {
            //Adding to an existing collection NOT creating a new one
            Friends = {"Steve", "Jim", "John"}
        };

【问题讨论】:

    标签: c# collections ienumerable


    【解决方案1】:

    Object and collection initializers 仅在“对象创建表达式”中有效,由new 关键字引入。来自 C# 4.0 规范的 §7.6.10.1:

    对象创建表达式:
    new   type   (   argument-listopt   )   object-or-collection-initializeropt
    new   type   object-or-collection-initializer

    对象或集合初始化器:
    对象初始化器
    集合初始化器

    从 §7.6.10.2 开始:

    对象初始化器由一系列成员初始化器组成,由{} 标记括起来并用逗号分隔。

    在等号之后指定集合初始值设定项的成员初始值设定项是嵌入式集合的初始化。初始化器中给出的元素被添加到字段或属性引用的集合中,而不是为字段或属性分配新集合。

    因此,以下是创建新 DataTable 并使用几个集合初始化器将项目添加到嵌入的 ColumnsRows 集合的法律声明:

    DataTable table =
        new DataTable  // <-- IMPORTANT
        {
            Columns = { { "Name", typeof(string) } },  // table.Columns.Add("Name", typeof(string));
            Rows = { "John" },                         // table.Rows.Add("John");
        };
    

    相比之下,下面的说法是无效的:

    table.Rows = { "John" };
    

    虽然表达式类似于集合初始化器,但它出现在对象创建表达式的上下文之外(任何地方都没有 new 关键字),因此编译器将语句解析为 table.Rows = ... 而不是 table.Rows.Add(...)

    在您的原始示例中,只需显式调用 Add 方法:

    _dt.Tables["TABLE"].Rows.Add(row);
    

    【讨论】:

    • 根据 C# In Depth (Jon Skeet) 的第 222 页,这是不正确的。集合初始化器“请注意,您不是在此处创建新集合,而是添加到现有集合中”[意思是不使用 new 关键字时]。
    • 没问题,我会尝试查找网络参考。
    • 请注意您的示例中的new Person这就是允许您使用对象和集合初始化器的原因!如果表达式开头没有new,则不能使用对象和集合初始化器。
    • Jon Skeet 也是正确的。我没有他的书的副本,但我完全希望集合初始化程序是更大的new 表达式的一部分:他创建一个新对象,然后将一个项目添加到 existing 集合那个 new 对象。他没有将项目添加到 existing 对象的现有集合中。
    • 我怀疑你在那儿一针见血,我的例子是乔恩的改编副本,所以它似乎站得住脚。
    猜你喜欢
    • 2016-02-25
    • 2019-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多