Что означает "апостроф + число" в типе объекта со свойствами дженериков (например, "Collection`1")?
У меня есть объект (MyObject
) с собственностью (MyProperty
). Я хочу получить его имя типа (т.е. String
или же MyClass
так далее.). Я использую:
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, версия =2.0.0.0, культура = нейтральная, PublicKeyToken=b77a5c561934e089]]
Что это такое `1
? И как можно получить Collection<String>
"?
3 ответа
``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 код @ 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).
}