Given a list of objects, I'd like to print a string version of them just in case the object.ToString() result is a relevant string.
By that I mean I don't want to get things like:
obj.ToString() -> System.Collections.Generic.List`1[MyLib.Dude]
obj.ToString() -> System.Collections.Generic.Dictionary`2[System.Int32,System.DateTime]
obj.ToString() -> System.Byte[]
But I want to get things like:
obj.ToString() -> Hi
obj.ToString() -> 129847.123
obj.ToString() -> Id = 123
What should be the best way to开发者_运维百科 implement this in a method:
Public Sub PrintInterestingStuffOnly(ByVal coolList as Ilist(Of Object))
For Each obj in coolList
'insert solution here
Console.WriteLine( ....
End For
End Sub
?
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);
}
}
This could be slow since it uses reflection to determine whether or not a particular type has overridden the ToString
method. A faster alternative might be to use a static cache to "remember" the result of the reflection so that it only needs to be done once per type:
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;
string.Join(", ", list);
If the list was composed of { 1, 2, 3, 4 }
, This will print out:
1, 2, 3, 4
(It will perform the .ToString()
implicitly, so you can use any sort of object.)
If Not obj.ToString().StartsWith("System.") Then
精彩评论