2012-02-05 59 views
0

我新在C#泛型和一邊看書時的例子偶然發現:使用仿製藥,而不是鑄造的AsEnumerable

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") 
    }; 

撰文人說,car.Field<string>("Color")給出了額外的編譯時檢查比較(string)car["Color"]。但是編譯器如何知道car.Field<string>("Color")可以編譯爲「Color」而不是「CarID」?或者我錯過了另一種「額外的編譯時檢查」?

+0

@DBM,'car'不是'IEnumerable ',它是'T'。 – svick 2012-02-05 23:14:11

+0

啊,你說得對。我很累...... T可能是一個'DataRow' – 2012-02-05 23:15:20

回答

2

它不會給你任何額外的編譯時檢查。如果你使用了錯誤的類型,在這兩種情況下你都會在運行時遇到異常。

但是,執行簡單轉換無法執行的其他內容可能很有用。例如Field<int>("CarId")可能會調用將該字段中的string轉換爲int的方法。

假設你在談論DataRow.Field<T>(),那麼根據文檔,它主要用於正確處理null值和可空類型。

0

編譯器不知道,您指定的字段「顏色」是字符串類型。在內部,Field<T>()方法實現這一點很神奇。

如果執行強制轉換((string)car["Color"]),如果字段值無法轉換爲目標類型,則可能會遇到運行時異常。

從內存中,如果指定car.Field<string>("ColorID"),則可以安全地將int轉換爲字符串,而不會出現任何問題。

0

具體來說,car.Field<string>("Color")的真正好處是它封裝了與DBNull.Value相等的測試字段值,使您的代碼更清晰易讀。

在你的榜樣,如果「顏色」字段的值爲null,該Field<T>擴展方法將返回null,而car["Color"]將返回DBNull.Value。您無法將DBNull.Value轉換爲string,因此表達式(string)car["Color"]在該情況下會產生InvalidCastException

DataSetExtensions類的開發之前,你需要一個有點繁瑣表達該字段的值賦給一個string變量:

var color = DBNull.Value.Equals(car["Color"]) ? null : (string)car["Color"]; 

Field<T>另一個好處是,作爲svick筆記,它使您能夠使用相同的語法使用可空類型和引用類型。