このコードは、ネストされたジェネリックタイプ(たとえばFoo<int>.Bar<string,object>
)で機能するはずです。
public static string GetCSharpTypeName(this Type type, bool getFullName)
{
StringBuilder sb = new StringBuilder();
if (getFullName && !string.IsNullOrEmpty(type.Namespace))
{
sb.Append(type.Namespace);
sb.Append(".");
}
AppendCSharpTypeName(sb, type, getFullName);
return sb.ToString();
}
private static void AppendCSharpTypeName
(StringBuilder sb, Type type, bool fullParameterNames)
{
string typeName = type.Name;
Type declaringType = type.DeclaringType;
int declaringTypeArgumentCount = 0;
if (type.IsNested)
{
if (declaringType.IsGenericTypeDefinition)
{
declaringTypeArgumentCount =
declaringType.GetGenericArguments().Length;
declaringType = declaringType.MakeGenericType(
type.GetGenericArguments().Take(declaringTypeArgumentCount)
.ToArray());
}
AppendCSharpTypeName(sb, declaringType, fullParameterNames);
sb.Append(".");
}
Type[] genericArguments = type.GetGenericArguments()
.Skip(declaringTypeArgumentCount).ToArray();
int stopIndex;
if ((type.IsGenericTypeDefinition || type.IsGenericType)
&& ((stopIndex = type.Name.IndexOf('`')) > 0))
{
sb.Append(typeName.Substring(0, stopIndex));
string[] genericArgumentNames = genericArguments
.Select(t => GetCSharpTypeName(t, fullParameterNames)).ToArray();
if (genericArgumentNames.Length > 0)
sb.AppendFormat("<{0}>", string.Join(",", genericArgumentNames));
}
else
{
sb.Append(typeName);
}
}
潜在的な特殊なケースがたくさんある素敵な例です。ちょっと注意すると、genArgsのforループはstring.Join( "、"、genArgs.Select(x => x.FullName))で置き換えることができます。速度に差がある場合は、Marcsコードが速いかもしれないが私は個人的には可読性のためにループの1つのライナーを好むでしょう –
とそれらを機能的に同等にするためには、選択のためにGetCSharpTypeName(T)を使用してください.FullName –
コードMarcのおかげで、あなたのコードは私の現在のコード私は、特定の複雑さ(または少なくとも外部関数)を含まない解決策を見つけることを望んでいました。 – NoizWaves