[英]What is type "object {string}"?
我有一本帶有此定義的Dictionary<string, object>
。 該字典填充了來自提交給 Web 服務器的表單的數據。
未提交的表單字段看起來像是在字典中設置的空字符串。 例如,如果表單字段MyFormField
未設置,則myDictionary["MyFormField"]
返回""
。
假設我從字典中得到一個看起來像空字符串的值,如下所示:
var formFieldValue = formValues[formFieldName]; // Populates the formFieldValue variable with the value ""
現在,在 Visual Studio 的立即窗口中,我對變量運行以下操作:
submittedFormFieldValue // => "" (just printing the value)
formFieldValue.GetType() == typeof(string) // => true
string.IsNullOrWhiteSpace(formFieldValue) // => error CS1503: Argument 1: cannot convert from 'object' to 'string'
formFieldValue.GetType() // => {Name = "String" FullName = "System.String"} ...
formFieldValue == string.Empty // => false
formFieldValue == "" // => false
所以,當我比較類型時,首先我會得到true
。 我得到該參數 1 無法從“對象”轉換為“字符串”。
在 Watch 窗口中, formFieldValue
的類型顯示為object {string}
,而不是我將formFieldValue as string
寫formFieldValue as string
,后者顯示為string
。
這個object {string}
類型是什么?
在compile-time ,變量是object
類型 - 這就是string.IsNullOrWhitespace
無法編譯的原因。
在執行時,變量的值是對字符串的引用。
這兩行:
formFieldValue == string.Empty
formFieldValue == ""
...正在比較引用標識,因為左操作數是對象類型。
我強烈懷疑如果你使用formFieldValue.Equals("")
那么它會返回true
。 同樣,如果您先轉換為字符串:
string formFieldStringValue = (string) formFieldValue;
if (formFieldStringValue == "")
{
...
}
...然后它將進入if
語句的主體,因為==
運算符使用重載的==(string, string)
運算符,它按文本而不是引用標識比較字符串。
如果您觀察以下代碼,您應該會看到與您所看到的行為的相似之處:
public void MyTestMethod(string s) { }
object o = "Hello StackOverflow!";
Console.WriteLine(o.GetType() == typeof(string)); // true
Console.WriteLine(o is string); // true
MyTestMethod(o); // error: cannot convert object to string
這里要注意的重要一點是o
是一個object
類型的變量。
當您調用GetType
,您會收到o
包含的內容的實際類型(它是一個字符串)。 同樣, is
查看實際類型。
但是o
本身(不是包含在其中的值!)仍然是一個object
,因此編譯器強制執行它。
您可以通過明確聲明編譯器應將其視為字符串來避免編譯器錯誤:
MyTestMethod((string)o); // works
// OR
MyTestMethod(o as string); // also works
但是,當您必須轉換變量時,在大多數情況下,這意味着您最初不應該將它們轉換為較低的類型(即object
而不是堅持使用string
)。
我無法為您做出這個決定,但如果您打算只使用字符串值,那么簡單地停止在字典中使用object
可能是明智的。 如果沒有,那么您將不得不檢查類型(或者盲目相信您永遠不會編寫導致運行時異常的代碼 - 這對於非平凡的項目來說是一個壞主意)。
您在這里處理相同問題的原因是您的字典將其值定義為object
s(因為Dictionary<string, object>
)
var x = myDict["foo"];
如果myDict
是Dictionary<string, object>
,則x
將始終是object
,無論您在字典中輸入了哪些值。
例如:
myDict["x"] = 5; // int
myDict["y"] = "5"; // string
myDict["z"] = 5f; // float
var x = myDict["x"]; // object
var y = myDict["y"]; // object
var z = myDict["z"]; // object
即使您可以推斷每個條目的類型, x
y
和z
將始終是object
類型,因為這是您的字典將其值定義為的類型。
要解決此問題,請不要使用object
作為您的字典值類型,或者顯式轉換/轉換您的值:
var x = myDict["x"] as int;
var x = (int) myDict["x"];
var x = Convert.ToInt32(myDict["x"]);
請記住,您真的應該在這里檢查解析/轉換失敗。 如果這是一個小而瑣碎的副項目,您也許可以保證您的代碼在做正確的事情,但對於任何規模合適的項目來說,這是一種危險且魯莽的方法。
在您的情況下, formValues
索引器返回一個對象,其具體類型是string
。
觀察窗口將它們顯示為“靜態類型{具體類型}”,這就是您所看到的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.