我有一个具有属性(MyProperty
(的对象(MyObject
(。我想得到它的类型名称(即String
或MyClass
等(。我使用:
PropertyInfo propInfo = typeof(MyObject).GetProperty("MyProperty");
Console.WriteLine(propInfo.PropertyType.Name);
Console.WriteLine(propInfo.PropertyType.FullName);
简单类型没有问题,但当MyProperty
是泛型类型时,我在获取它的名称(例如Collection<String>
(时会遇到问题。它打印:
集合`1
System.Collections.ObjectModel.Collection`1[[System.String,mscorlib,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089]
`1
是什么?如何获取"Collection<String>
">
`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();
}
这是CLR内部类型名。
数字是泛型类型参数的数量,因为类型可以重载
(Func`1
和Func`2
是不同类型(
没有内置的方法来获得C#风格的类型名,因为CLR与C#无关。
SLaks已经解释了`1的含义。
关于您的第二个问题:您可以使用type.GetGenericArguments:获得泛型类型参数的名称
if (propInfo.PropertyType.IsGenericType) {
Type[] typeArguments = propInfo.PropertyType.GetGenericArguments();
// typeArguments now contains an array of types ({String} in your example).
}