[英]Using generics instead of casting for AsEnumerable
I am new to generics in C# and while reading a book stumbled upon an example: 我不熟悉C#中的泛型,在阅读一本书时偶然发现了一个例子:
var cars = from car in data.AsEnumerable()
where
car.Field<string>("Color") == "Red"
select new
{
ID = car.Field<int>("CarID"),
Make = car.Field<string>("Make")
};
The author says that car.Field<string>("Color")
gives the additional compile-time checking comparing to (string)car["Color"]
. 作者说car.Field<string>("Color")
给出了与(string)car["Color"]
相比较的额外编译时检查。 But how does the compiler know that car.Field<string>("Color")
is compilable for "Color" and not for "CarID"? 但编译器如何知道car.Field<string>("Color")
可编译为“Color”而不是“CarID”? Or there is some kind of another "additional compile-time checking" that I miss? 还是有一些我想念的“额外的编译时检查”?
It doesn't give you any additional compile-time checking. 它不会为您提供任何额外的编译时检查。 If you use the wrong type, in both cases you'll get an exception during run-time. 如果使用错误的类型,在这两种情况下,您将在运行时获得异常。
But it can be useful to do additional stuff that simple cast can't. 但是做一些简单的演员不能做的额外的事情会很有用。 For example Field<int>("CarId")
could call a method that converts the string
in the field to an int
. 例如, Field<int>("CarId")
可以调用一个方法,将字段中的string
转换为int
。
And assuming you're talking about DataRow.Field<T>()
, then, according to the documentation, it's useful mostly for dealing with null
values and nullable types correctly. 假设您正在讨论DataRow.Field<T>()
,那么,根据文档,它主要用于正确处理null
值和可空类型。
The compiler doesn't know, your specifying that field "Color" is of type string. 编译器不知道,您指定字段“Color”是字符串类型。 Internally, the Field<T>()
method does it's magic to make that happen. 在内部, Field<T>()
方法可以实现这一点。
If you perform a cast ( (string)car["Color"]
) you could encounter a runtime exception if the field value cannot be converted to the destination type. 如果执行强制转换( (string)car["Color"]
),如果字段值无法转换为目标类型,则可能会遇到运行时异常。
From memory, if you specify car.Field<string>("ColorID")
, you will be able to safely convert int to string without any issues. 从内存中,如果指定car.Field<string>("ColorID")
,您将能够安全地将int转换为字符串而不会出现任何问题。
Specifically, the real benefit of car.Field<string>("Color")
is that it encapsulates testing field values for equality with DBNull.Value
, making your code cleaner and easier to read. 具体来说, car.Field<string>("Color")
的真正好处是它使用DBNull.Value
封装测试字段值,使代码更清晰,更易于阅读。
In your example, if the value of the "Color" field is null, the Field<T>
extension method will return null
, while car["Color"]
will return DBNull.Value
. 在您的示例中,如果“Color”字段的值为null,则Field<T>
扩展方法将返回null
,而car["Color"]
将返回DBNull.Value
。 You can't cast DBNull.Value
to string
, so the expression (string)car["Color"]
raises an InvalidCastException
in that case. 您不能将DBNull.Value
InvalidCastException
为string
,因此表达式(string)car["Color"]
在这种情况下会引发InvalidCastException
。
Before the development of the DataSetExtensions
class, you would need a somewhat verbose expression to assign the value of that field to a string
variable: 在开发DataSetExtensions
类之前,您需要一个有点冗长的表达式来将该字段的值赋给string
变量:
var color = DBNull.Value.Equals(car["Color"]) ? null : (string)car["Color"];
Another benefit of Field<T>
is, as svick notes, that it enables you to work with nullable types and reference types using the same syntax. 正如svick所说, Field<T>
另一个好处是,它使您能够使用相同的语法处理可空类型和引用类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.