【问题标题】:A neater GetType().ToString() for closed generics用于封闭泛型的更简洁的 GetType().ToString()
【发布时间】:2013-01-11 18:43:03
【问题描述】:

我不敢相信以前没有人问过这个问题,但是因为我无法在 stackoverflow haystack 中找到这个特殊的“针”,所以我在问它。

我想要一个更简洁的 GetType().ToString() 实现,用于封闭的泛型类型。更简洁的意思是我希望 ToString() 调用以我在开发环境中输入的格式返回一个字符串。

封闭泛型上的默认 GetType().ToString() 将放置 `n 其中 n 是类型的数量,并使用 [ ] 代替 的。

无论如何...到代码。

给定以下类:

A a = new A();
C<A> c = new C<A>();
D<A, B> d = new D<A, B>();
E<B, C<A>, D<A, B>> e = new E<B, C<A>, D<A, B>>();

默认.ToString()返回:

AAA.Events.A
AAA.Events.C`1[AAA.Events.A]
AAA.Events.D`2[AAA.Events.A,AAA.Events.B]
AAA.Events.E`3[AAA.Events.B,AAA.Events.C`1[AAA.Events.A],AAA.Events.D`2

我已经编写了一些基本的老式(pre linq)代码来生成:

AAA.Events.A
AAA.Events.C<AAA.Events.A>
AAA.Events.D<AAA.Events.A,AAA.Events.B>
AAA.Events.E<AAA.Events.B,AAA.Events.C<AAA.Events.A>,AAA.Events.D<AAA.Events.A,AAA.Events.B>>

但我真的很希望它返回:

A
C<A>
D<A,B>
E<B,C<A>,D<A,B>>

这是我为证明我的意图而编写的伪劣代码:

public static string NeaterString(this Type t)
{
    string neater = t.ToString();
    if (neater.Contains('`'))
    {
        while (neater.Contains('`'))
        {
            neater = neater.Remove(neater.IndexOf('`'), 2);
        }
        return neater.Replace('[', '<').Replace(']', '>');
    }
    else return neater; 
}

【问题讨论】:

  • 我注意到您没有在测试用例中包含嵌套的泛型类型。我也会有点担心你的方法对数组做了什么。
  • 我的代码更像是一个业余 VBA hack,而不是真正的代码,我向你保证我无意使用它。我写它是为了表达这个问题,并正在寻找 Linq-i-fied 的解决方案。出于兴趣,如果不是 E,D>,什么是嵌套泛型类型。
  • class A&lt;T&gt; { public class B&lt;U&gt; { } } -- (new A&lt;int&gt;.B&lt;double&gt;()).GetType().ToString() 的结果是什么?将相同类型传递给NeaterString 的结果是什么?

标签: c#


【解决方案1】:

我会尽量避免字符串解析。我的日常是这样的:

public static string GetFriendlyName(Type type)
{
    if (type.IsGenericType)
        return string.Format("{0}<{1}>", type.Name.Split('`')[0], string.Join(", ", type.GetGenericArguments().Select(x => GetFriendlyName(x))));
    else
        return type.Name;
}

【讨论】:

  • 您可以通过将方法组直接传递给 Select 来避免分配 lambda。即:.Select(GetFriendlyName).
【解决方案2】:

更多的是霰弹枪方法:

public static class TypeExtensions
{
    public static string PrettyPrint(this Type type)
    {
        var str = type.ToString();

        for (int i = 1; i < 6; i++)
        {
            str = str.Replace($"`{i}[", "<");
        }

        str = str.Replace("]", ">");

        var knownNamespaces = new[]
        {
            "System.",
            "My.Models.",
            "Domain."
        };

        foreach (var knownNamespace in knownNamespaces)
        {
            str = str.Replace(knownNamespace, string.Empty);
        }

        return str;
    }
}

如果你有超过`5的超复杂泛型,你可以增加i的限制[

【讨论】:

    【解决方案3】:

    我正在尝试这样做,并且我还需要能够解析这些字符串以将它们转换回类型变量。

    Here's the code I wrote。它可以将任何类型转换为与 C# 语法完全相同的字符串,并且可以将这些字符串转换回类型变量。完全支持泛型,包括未绑定的泛型。希望对你有帮助:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-03
      相关资源
      最近更新 更多