TypedDataSet:为什么.NET Framework在int datatable列中接受字符串?

时间:2009-10-25 10:18:12

标签: c#

这里http://www.c-sharpcorner.com/UploadFile/rupadhyaya/TypedDataSets12032005021013AM/TypedDataSets.aspx它说: “我们可以在为DataTable创建DataColumn时指定数据类型。这是为了强制列的运行时类型安全性,以便只有指定数据类型的数据可以存储在列中。同样,在大多数情况下我们更喜欢将DataSet本身设置为Type-safe,以保护它免受运行时不匹配的影响。因此Typed DataSet生成的类以类型安全的方式公开DataSet中的每个对象。这些类直接从DataSet类继承。 “

但这可行,但它不应该因为我存储id.ToString()而不是在typeof(int)id列中的id?

using System;
using System.Data;

public class MyClass {

    public static void Main() {

        DataTable custTable = new DataTable("Customers");
        // add columns
        custTable.Columns.Add("id", typeof(int));
        custTable.Columns.Add("name", typeof(string));
        custTable.Columns.Add("address", typeof(string));

        // set PrimaryKey
        custTable.Columns[ "id" ].Unique = true;
        custTable.PrimaryKey = new DataColumn[] { custTable.Columns["id"] };

        // add ten rows
        for(int id=1; id<=10; id++)
        {
            custTable.Rows.Add(
                new object[] { id.ToString(), string.Format(
                "customer{0}", id.ToString()), string.Format("address{0}", id.ToString()) });
        }

        custTable.AcceptChanges();

        foreach (DataRow row in custTable.Rows) {
            Console.WriteLine("{0} {1}",row["id"],row["name"]);
        }
        Console.ReadLine();
    }   
}

4 个答案:

答案 0 :(得分:3)

您的示例不是编译器的责任区域。你创建对象数组,这里没有错误

也许你问为什么这个字符串值被数据库接受为int值?可能是您的库识别id.ToString作为一个正确的整数或可能是由数据库引擎完成。因为在SQL级别都转换为只是文本

答案 1 :(得分:1)

因为编译器不知道DataTable类应该和不应该接受什么。

rows collection的Add方法需要一堆Object引用,因此将所需的任何数据类型发送到它中是有效的。它尝试在运行时转换数据,如果发送一些无法转换的数据,则会出现运行时错误。

答案 2 :(得分:1)

您应该阅读您链接到的文章的其余部分,而不仅仅是第一句话。您发布的代码会创建无类型数据集。使用DataSet Designer创建类型的 DataSet,并且实际上在编译时强制执行类型安全。在类型化的DataSet中,你有一个CustomersRow类,它暴露了一个int id属性和字符串nameaddress属性,你得到一个编译时如果您尝试将id设置为字符串值,则会出错。

实际上,如果可以的话,ADO类会在运行时将值转换为适当的数据类型。因此,即使您的代码将id设置为字符串,实际存储在DataRow中的数据也是一个整体 - 尝试将id设置为“a”并且您将获得运行 - 时间错误。这也是相反的方式;如果将customer设置为整数11,您会发现它实际上包含字符串“11”。

答案 3 :(得分:0)

DataTable类就像一个字符串列名称&amp;的查找表。对象值,编译器不使用您传递的类型参数。