簡體   English   中英

如何確定 object 是否可以將 ToString 轉換為值或類型名稱?

[英]How can I determine if an object can ToString into value or type name?

我正在編寫 php 服務和我們的 crm 之間的互操作。 我需要做的一件事是確保將簡單類型轉換為 ToString() 以便稍后在 json 轉換器中使用。

我什至不確定'簡單類型'的名稱是什么,但它可以這樣定義......“代表低級變量類型的 object,包含單個值,而不是 class 或任何具有可執行功能等的東西”

我發現 int、string、bool、double 和令人驚訝的 enum 將為 ToString() 提供相當可預測的結果。

int x = 0;
bool y = true;
double z = 1.59 // money
CustomEnum theEnum = CustomEnum.somevalue;

x.ToString() 結果為“0”

y.ToString() 結果為“真”

z.ToString() 結果為“1.59”

theEnum.ToString() 產生“somevalue”

但如果我使用這個:

List<int> iList = new List<int>();
iList.Add(1);

MyClass theClass = new MyClass();

iList.ToString() 導致“System.Collections.Generic.List`1[System.Int32]” theClass.ToString() 導致“STTI.NKI.Interop.MyClass”

我不限於列表。 我可以有一個 ExpandoObject,或者一個 class 等。

我完全理解為什么會發生這種情況,我想知道是否有一種快速方法來確定未知類型的 object 是否會將 ToString() 轉換為預期值,而不是類型名稱。 我發現做類似的事情是一種反模式

switch (theObject.GetType())
 case typeof(int):
 case typeof(bool):
 case typeof(doulble):
etc

我不確定這些術語是什么,所以用谷歌搜索我的答案很困難。

因此,您想檢查一個類型是否具有重寫的ToString方法嗎? 為什么不通過檢查返回值是否ToString是等於默認實現返回值ToString

這里 ,我們知道ToString的默認實現是

return GetType().ToString();

因此,我們可以使用它來檢查對象是否重寫了ToString方法:

bool toStringOverridden = someObject.GetType().ToString() !=
    someObject.ToString();

ToString方法是一個虛擬的方法,默認實現在Object類中定義,並且僅返回對象類型的名稱:

public virtual string ToString()
{
  return this.GetType().ToString();
}

例如, int重寫此方法以返回有意義的表示形式。

您可以使用反射來檢測類型是否覆蓋ToString方法,如下所示:

public static bool OverridesToString(Type type)
{
    return type.GetMethod("ToString", new Type[0]).DeclaringType != typeof(object);
}

如果是這樣,則ToString方法很有可能返回有意義的東西。

選項1:確保每個對象都將覆蓋ToString()。 選項2:使用反射獲取所有對象屬性並合並它們。

也許您可以執行以下操作:

bool ToStringIsTyped<T>(T myObj)
{
    return myObj.ToString().Contains(typeof(T).FullName);
}

它可能並非在所有情況下都有效,但可能會擴展

我認為這就是您要查找的內容,在GetMethod中,第二個參數是一個空數組,用於監視.ToString(),只需轉換i.GetType().GetMethod("ToString", new Type[] { }).DeclaringType == typeof(object)到一個函數,然后就可以了。

class Program
    {
        static void Main(string[] args)
        {
            int i = 55;
            var s = "some string";
            var x = new List<string>();
            Console.WriteLine(i.ToString());
            Console.WriteLine(i.GetType().GetMethod("ToString", new Type[] { }).DeclaringType == typeof(object));
            Console.WriteLine(s.ToString());
            Console.WriteLine(s.GetType().GetMethod("ToString",new Type[]{}).DeclaringType == typeof(object));
            Console.WriteLine(x.ToString());
            Console.WriteLine(x.GetType().GetMethod("ToString",new Type[]{}).DeclaringType == typeof(object));
        }
    }

...確定類型未知的對象是否會將ToString()轉換為期望值,而不是類型名稱的方法...

根據文檔 ,對objectToString()的默認實現返回“對象類型的完全限定名稱”。

因此,我們可以提出一個假設,即無論何時重寫ToString(),其輸出在問題中指定的意義上都是“有用的”。

為了檢測一個被調用的函數是否是一個覆蓋,我們可以像這樣使用這個答案

if(typeof(ObjectX).GetMethod("ToString").DeclaringType == typeof(ObjectX))
{
    /* ObjectX has overridden ToString() */
}
else
{
    /* ObjectX has inherited ToString() from its base class(es) */
}

使用反射會增加太多開銷,所以我認為最好創建一個通用方法並添加一個約束,例如: where T: IFormattable

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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