簡體   English   中英

什么是“對象 {string}”類型?

[英]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 stringformFieldValue 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"];

如果myDictDictionary<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 yz將始終是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM