2011-02-15 42 views
1

給定一個對象的列表,我想打印他們的字符串版本,以防萬一object.ToString()結果是一個相關的字符串。從列表<object>,ToString()他們只是當他們是原始類型或有此方法覆蓋

我的意思是我不希望得到的東西,如:

obj.ToString() -> System.Collections.Generic.List`1[MyLib.Dude] 
obj.ToString() -> System.Collections.Generic.Dictionary`2[System.Int32,System.DateTime] 
obj.ToString() -> System.Byte[] 

但我想要得到的東西,如:

obj.ToString() -> Hi 
obj.ToString() -> 129847.123 
obj.ToString() -> Id = 123 

什麼應該在實施這一目標的最佳方式方法:

Public Sub PrintInterestingStuffOnly(ByVal coolList as Ilist(Of Object)) 
    For Each obj in coolList 
     'insert solution here 
     Console.WriteLine(.... 
    End For 
End Sub 

+1

想到的第一件事就是測試obj.ToString ()== obj.GetType()。ToString() – walkingTarget 2011-02-15 15:06:36

+1

你怎麼能說它是相關的?您是否對每種情況下的做法都有明確的規定?例如,當沒有ToString()被覆蓋? – decyclone 2011-02-15 15:07:27

回答

3
var bf = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly; 
foreach (var item in coolList) 
{ 
    Type t = item.GetType(); 
    if (t.IsPrimitive 
     || (t.GetMethod("ToString", bf, null, Type.EmptyTypes, null) != null)) 
    { 
     Console.WriteLine(item); 
    } 
} 

這可能會很慢,因爲它使用反射來確定某個特定類型是否已覆蓋了方法ToString。更快的替代方案可能是使用靜態緩存來「記住」反射的結果,以便每種類型只需要執行一次:

foreach (var item in coolList) 
{ 
    Type t = item.GetType(); 
    if (t.IsPrimitive || _cache.GetOrAdd(t, _factory)) 
    { 
     Console.WriteLine(item); 
    } 
} 

// ... 

private static readonly ConcurrentDictionary<Type, bool> _cache = 
    new ConcurrentDictionary<Type, bool>(); 

private const BindingFlags _flags = 
    BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly; 

private static readonly Func<Type, bool> _factory = 
    t => t.GetMethod("ToString", _flags, null, Type.EmptyTypes, null) != null; 
2
string.Join(", ", list); 

如果列表組成的{ 1, 2, 3, 4 },這將打印出:

1,2,3,4

(它會隱式地執行.ToString(),這樣你就可以使用任何種類的物體)。

0
If Not obj.ToString().StartsWith("System.") Then 
相關問題