我需要某種方式來獲取類型的名稱,當type.IsGenericType
= true
。C#獲取泛型類型名稱
Type t = typeof(List<String>);
MessageBox.Show(..?..);
我想要的,是一個消息框,List
描述了...我怎麼能做到這一點彈出?
我需要某種方式來獲取類型的名稱,當type.IsGenericType
= true
。C#獲取泛型類型名稱
Type t = typeof(List<String>);
MessageBox.Show(..?..);
我想要的,是一個消息框,List
描述了...我怎麼能做到這一點彈出?
Type t = ...;
if (t.IsGenericType)
{
Type g = t.GetGenericTypeDefinition();
MessageBox.Show(g.Name); // displays "List`1"
MessageBox.Show(g.Name.Remove(g.Name.IndexOf('`'))); // displays "List"
}
假設你只是想看看它的List<T>
代替List<string>
你需要做的:
MessageBox.Show(t.GetGenericTypeDefinition().FullName)
見http://msdn.microsoft.com/en-us/library/system.type.getgenerictypedefinition.aspx
您可以實現一個擴展方法來獲得「友好名稱「,如下所示:
public static class TypeNameExtensions
{
public static string GetFriendlyName(this Type type)
{
string friendlyName = type.Name;
if (type.IsGenericType)
{
int iBacktick = friendlyName.IndexOf('`');
if (iBacktick > 0)
{
friendlyName = friendlyName.Remove(iBacktick);
}
friendlyName += "<";
Type[] typeParameters = type.GetGenericArguments();
for (int i = 0; i < typeParameters.Length; ++i)
{
string typeParamName = typeParameters[i].Name;
friendlyName += (i == 0 ? typeParamName : "," + typeParamName);
}
friendlyName += ">";
}
return friendlyName;
}
}
有了這個項目,你現在可以說:
MessageBox.Show(t.GetFriendlyName());
它會顯示「列表<字符串>」。
我知道OP沒有要求泛型類型參數,但我更喜歡這種方式。 ;-)
命名空間和standard aliases for built-in types作爲練習給讀者。
隨着新的C#可愛,你現在可以在一個(雖然很長)的行中寫反引號檢查後的所有位,這也將處理嵌套泛型: 'friendlyName + = $「<{string.Join(」,「,type.GetGenericArguments()。Select(p => type.GetFriendlyName()))}>」' – joshcomley 2017-11-28 05:34:17
我改進了代碼生成中使用的yoyos版本。 請注意,現在所有類型都被引用full qualified => global :: System.String。
public static string GetFriendlyTypeName(Type type)
{
string friendlyName = type.Name;
if (type.IsGenericType)
{
int iBacktick = friendlyName.IndexOf('`');
if (iBacktick > 0)
{
friendlyName = friendlyName.Remove(iBacktick);
}
friendlyName += "<";
Type[] typeParameters = type.GetGenericArguments();
for (int i = 0; i < typeParameters.Length; ++i)
{
string typeParamName = GetFriendlyTypeName(typeParameters[i]);
friendlyName += (i == 0 ? typeParamName : "," + typeParamName);
}
friendlyName += ">";
friendlyName = "global::" + type.Namespace + "." + friendlyName;
}
else
{
friendlyName = "global::" + type.FullName;
}
return friendlyName.Replace('+', '.');
}
public static class TypeNameExtensions
{
public static string GetFriendlyName(this Type type)
{
var friendlyName = type.Name;
if (!type.IsGenericType) return friendlyName;
var iBacktick = friendlyName.IndexOf('`');
if (iBacktick > 0) friendlyName = friendlyName.Remove(iBacktick);
var genericParameters = type.GetGenericArguments().Select(x => x.GetFriendlyName());
friendlyName += "<" + string.Join(", ", genericParameters) + ">";
return friendlyName;
}
}
我採取的對YOYO的做法。爲基元確保更友好的名稱,處理數組,並遞歸處理嵌套泛型。也是單元測試。
private static readonly Dictionary<Type, string> _typeToFriendlyName = new Dictionary<Type, string>
{
{ typeof(string), "string" },
{ typeof(object), "object" },
{ typeof(bool), "bool" },
{ typeof(byte), "byte" },
{ typeof(char), "char" },
{ typeof(decimal), "decimal" },
{ typeof(double), "double" },
{ typeof(short), "short" },
{ typeof(int), "int" },
{ typeof(long), "long" },
{ typeof(sbyte), "sbyte" },
{ typeof(float), "float" },
{ typeof(ushort), "ushort" },
{ typeof(uint), "uint" },
{ typeof(ulong), "ulong" },
{ typeof(void), "void" }
};
public static string GetFriendlyName(this Type type)
{
string friendlyName;
if (_typeToFriendlyName.TryGetValue(type, out friendlyName))
{
return friendlyName;
}
friendlyName = type.Name;
if (type.IsGenericType)
{
int backtick = friendlyName.IndexOf('`');
if (backtick > 0)
{
friendlyName = friendlyName.Remove(backtick);
}
friendlyName += "<";
Type[] typeParameters = type.GetGenericArguments();
for (int i = 0; i < typeParameters.Length; i++)
{
string typeParamName = typeParameters[i].GetFriendlyName();
friendlyName += (i == 0 ? typeParamName : ", " + typeParamName);
}
friendlyName += ">";
}
if (type.IsArray)
{
return type.GetElementType().GetFriendlyName() + "[]";
}
return friendlyName;
}
[TestFixture]
public class TypeHelperTest
{
[Test]
public void TestGetFriendlyName()
{
Assert.AreEqual("string", typeof(string).FriendlyName());
Assert.AreEqual("int[]", typeof(int[]).FriendlyName());
Assert.AreEqual("int[][]", typeof(int[][]).FriendlyName());
Assert.AreEqual("KeyValuePair<int, string>", typeof(KeyValuePair<int, string>).FriendlyName());
Assert.AreEqual("Tuple<int, string>", typeof(Tuple<int, string>).FriendlyName());
Assert.AreEqual("Tuple<KeyValuePair<object, long>, string>", typeof(Tuple<KeyValuePair<object, long>, string>).FriendlyName());
Assert.AreEqual("List<Tuple<int, string>>", typeof(List<Tuple<int, string>>).FriendlyName());
Assert.AreEqual("Tuple<short[], string>", typeof(Tuple<short[], string>).FriendlyName());
}
}
這是我對此的看法。因爲我所看到的,它始終存在,所以我沒有進行反向檢查。你可以添加它,如果你想,但我喜歡保持簡單。
public static string GetFriendlyName(this Type type)
{
if (type.IsGenericType)
{
var name = type.Name.Substring(0, type.Name.IndexOf('`'));
var types = string.Join(",", type.GetGenericArguments().Select(GetFriendlyName));
return $"{name}<{types}>";
}
else
{
return type.Name;
}
}
如果你需要一個通用型的T型像'名單'你可以使用這樣的事情't.GetGenericArguments()[0] .Name'。我不久前需要這個,並且無法在任何地方找到它。這將返回字符串,如果你有一個'List'列表' –
2016-03-31 00:27:01