“撇号+数字”在泛型属性的对象类型中是什么意思(例如:“Collection`1”)?

10

我有一个对象 (MyObject),其中有一个属性 (MyProperty)。 我想获取它的类型名称(例如 StringMyClass 等)。 我使用:

PropertyInfo propInfo = typeof(MyObject).GetProperty("MyProperty");
Console.WriteLine(propInfo.PropertyType.Name);
Console.WriteLine(propInfo.PropertyType.FullName);

对于简单类型没有问题,但当MyProperty是一个泛型类型时,我在获取它的名称(例如Collection<String>)时会遇到问题。它输出:

Collection`1

System.Collections.ObjectModel.Collection`1[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]

那个`1是什么意思?我怎样才能获得"Collection<String>"?


2
Collection`1 意味着具有 1 个泛型类型参数的通用集合。 - Leom Burke
3个回答

11

`1表示一个泛型类型,具有1个泛型参数。

获取字符串的一种方法是使用System.CodeDom,如@LukeH所建议的那样:

using System;
using System.CodeDom;
using System.Collections.Generic;
using Microsoft.CSharp;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var p = new CSharpCodeProvider())
            {
                var r = new CodeTypeReference(typeof(Dictionary<string, int>));
                
                Console.WriteLine(p.GetTypeOutput(r));
            }
        }
    }
}

另一种方法在这里。 请看下面@jaredpar的代码:

public static string GetFriendlyTypeName(Type type) {
    if (type.IsGenericParameter)
    {
        return type.Name;
    }

    if (!type.IsGenericType)
    {
        return type.FullName;
    }

    var builder = new System.Text.StringBuilder();
    var name = type.Name;
    var index = name.IndexOf("`");
    builder.AppendFormat("{0}.{1}", type.Namespace, name.Substring(0, index));
    builder.Append('<');
    var first = true;
    foreach (var arg in type.GetGenericArguments())
    {
        if (!first)
        {
            builder.Append(',');
        }
        builder.Append(GetFriendlyTypeName(arg));
        first = false;
    }
    builder.Append('>');
    return builder.ToString();
}

你可能想要处理可空类型,并且在逗号后面添加一个空格。 - SLaks
如果您复制了完整的源代码,您可能希望给JaredPar更多的信誉,而不仅仅是一个指向问题的链接... - Heinzi
type.GetGenericTypeDefinition().FullName - SLaks
@SLaks,这会给出相同的结果(使用1)。 - George Duckett

8

这是CLR内部的类型名称。

数字表示泛型类型参数数量,因为类型可以重载。
(Func`1Func`2 是不同的类型)

没有内置的方法来获取C#风格的类型名称,因为CLR与C#无关。


5
您可以使用 CodeDom 获取 C# 风格的名称,但我觉得没有必要!以下是示例代码:using (var p = new CSharpCodeProvider()) { var r = new CodeTypeReference(propInfo.PropertyType); Console.WriteLine(p.GetTypeOutput(r)); } - LukeH
@LukeH:从源代码来看,它只处理数组,而不是泛型。 - SLaks
3
@LukeH,我认为那个评论应该作为一个回答。 - George Duckett

0

SLaksе·Із»Ҹи§ЈйҮҠдәҶ`1зҡ„еҗ«д№үгҖӮ

е…ідәҺдҪ зҡ„第дәҢдёӘй—®йўҳпјҡдҪ еҸҜд»ҘдҪҝз”ЁType.GetGenericArgumentsиҺ·еҸ–жіӣеһӢзұ»еһӢеҸӮж•°зҡ„еҗҚз§°пјҡ

if (propInfo.PropertyType.IsGenericType) {
    Type[] typeArguments = propInfo.PropertyType.GetGenericArguments();
    // typeArguments now contains an array of types ({String} in your example).
}

1
他需要一个字符串,而不是类型参数的数组。 - SLaks
@SLaks:好观点。我会把这留给读者作为练习。;-) - Heinzi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接