2011-06-13 45 views
4

任何人都可以請告訴我爲什麼下面的第一個語句會引發編譯錯誤,第二個語句不會呢?空煤炭操作員 - 爲什麼要鑄造?

NewDatabase.AddInParameter(NewCommand, "@SomeString", DbType.String, SomeString ?? DBNull.Value); // <-- Throws compilation error! 
NewDatabase.AddInParameter(NewCommand, "@SomeString", DbType.String, (object)(SomeString) ?? DBNull.Value); // <-- Compiles! 

我試過其他可空類型,如byte?,得到了相同的結果。任何人都可以告訴我爲什麼我需要首先投射物體?

+0

究竟是編譯錯誤? NewDatabase.AddInParameter的簽名是什麼? – Vlad 2011-06-13 16:23:12

+1

簽名是'void AddInParameter(DbCommand,string,DBType,object)'。編譯錯誤是「運營商」??不能應用於'string'和'System.DBNull'類型的操作數「。 – 2011-06-13 16:24:11

+0

相關問題 - http://stackoverflow.com/questions/13698421/is-if-condition-better-than-and-casting – Lijo 2012-12-04 16:57:21

回答

10

您需要告訴編譯器使用哪種類型。空合併運算符的結果類型必須與操作數類型的一個一個相同(或者在某些情況下,如果它是可爲空的值類型,則爲第一個操作數的基礎類型)。它並沒有試圖找到「兩種操作數都可以轉換成的最具體類型」或類似的東西。

有關的語言是如何當它涉及到的空合併運算符規定的詳情,請參閱C# 4 language specification,部分7.13:

類型表達a ?? b取決於其隱式轉換都可以在操作數。按優先順序,的a ?? b類型是A0A,或B,其中Aa類型(條件是a具有類型),Bb類型(前提是b具有類型),和A0A的基本類型,如果A是可以爲空的類型,則爲A,否則爲A

4

這是因爲null-coalescing操作符右側的類型必須隱式轉換爲左側的類型(反之亦然)。對於你的第一個例子,涉及的類型是stringDBNull。這些類型無關,所以轉換失敗。

+0

轉換也可以反過來 - 從左到右。 – 2011-06-13 16:28:09

2

DBValue.Null不是字符串;這是一個對象。 .NET不會在表達式中隱式轉換爲Object;必須明確告訴你期望得到一個Object結果。

2

因爲表達式需要一個返回類型。由於StringDbValue不能互相轉換,因此編譯器無法確定您想要哪種類型的返回。當您投射到Object時,您將爲編譯器提供可投射到的類型。