从列表, ToString() 仅当它们是原始类型或重写此方法时

发布于 2024-10-17 15:15:29 字数 686 浏览 5 评论 0原文

给定一个对象列表,我想打印它们的字符串版本,以防 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

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

?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

jJeQQOZ5 2024-10-24 15:15:29
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;
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;
讽刺将军 2024-10-24 15:15:29
string.Join(", ", list);

如果列表由 { 1, 2, 3, 4 } 组成,则会打印出:

1、2、3、4

(它将隐式执行.ToString(),因此您可以使用任何类型的对象。)

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.)

脸赞 2024-10-24 15:15:29
If Not obj.ToString().StartsWith("System.") Then 
If Not obj.ToString().StartsWith("System.") Then 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文