开发者

From a list<object> , ToString() them just when they are primitive types or have this method overriden

开发者 https://www.devze.com 2023-02-10 09:22 出处:网络
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.

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 
0

精彩评论

暂无评论...
验证码 换一张
取 消