我最近开始使用.NET编程,并查看了VB.NET和C#。 在VB.NET中,强类型数据表由强类型行的集合组成。因此,例如,此声明可以起作用:
lCustomerTable As CustomerDataSet.CustomerTable
lCustomerRow as CustomerDataSet.CustomerTable.CustomerRow
lCustomerTable = TableAdapter.GetData
lCustomerRow = lCustomerTable.Rows(0)
但是在C#中,我似乎必须将返回的行显式地转换为CustomerRow:
lCustomerRow = (CustomerDataSet.CustomerTable.CustomerRow)lCustomerTable.Rows[0]
这有什么理由吗?在创建表适配器和SQL dataTable时,数据集是否应该不创建对象类型定义?
答案 0 :(得分:3)
我认为Rows
实际上并不是强类型的,即使对于类型化数据集也是如此。不同之处在于,默认情况下,VB允许隐式向下转换。例如。你可以写:
Dim o As Object = ""
Dim s As String
s = o ' implicit downcast from Object to String!
只有在使用Option Strict
时才会禁用此功能 - 在VB中尝试并查看代码是否仍在编译...
在C#中,向下转换必须始终是显式的 - 它没有“非严格模式”。
答案 1 :(得分:3)
Pavel对你所看到的结果是正确的,因为它是一个缩小的转换。但是,施法不是答案。
Rows属性在DataTable类中定义,并且是DataRowCollection。但是,强类型DataTable中定义了一个属性,用于处理返回强类型行。
在VB.Net中:
Public Default ReadOnly Property Item(ByVal index As Integer) As CustomerRow
Get
Return CType(Me.Rows(index), CustomerRow)
End Get
End Property
在C#中:
public CustomerRow this[int index] {
get {
return ((CustomerRow)(this.Rows[index]));
}
}
正如您所看到的,它仍在构建行,但重点是它是在代码之外处理的,这样您就可以专注于按照预期的方式使用强类型数据集。因此,您应该使用它的方式,上面的代码将被重写为以下内容。
在VB.Net中:
lCustomerRow = lCustomerTable(0)
在C#中:
lCustomerRow = lCustomerTable[0];
另一个需要注意的重要事项是CustomerTable实现了IEnumberable< CustomerRow>,这意味着当你执行foreach循环(或任何带有LINQ的东西)时,你应该使用表本身而不是Rows属性,如下所示:
foreach (CustomerRow row in lCustomerTable) { DoSomethingWith(row); }
希望这有助于解决任何人的困惑。我最近没有使用数据集(打字或其他),因为我开始使用LINQtoSQL,它更好地能够以强类型方式处理数据。 EntityFramework可能是相同的,但我还没有像L2S一样进入它。 ;)
答案 2 :(得分:0)
[编辑] 我认为答案是实际投射返回的数据行:
lCustomerRow =(CustomerDataSet.CustomerRow)lMyCustomer.Rows [i];
可惜,因为我原以为Dataset.xsd应该包含这个转换信息。