C# Reflection: 如何获取 List<Employee> 而不是 System.Collections.Generic.List'1[Employee]?



我正试图使用反射来查询类库的公共接口,然后从查询中的信息中生成类和方法。

问题是生成的源代码无法编译:

  • 原始类库具有一个函数参数列表<员工>";,但是生成的源代码具有"0">System.Collections.Generic.List`1[员工]";。它由Type.ToString((.生成

  • 原始类库具有">词典<字符串,Employee>";,但是生成的代码具有"0">System.Collections.Generic.Dictionary `2[string,Employee]"。

以下是生成源代码的反射代码:

foreach (MethodInfo methodInfo in type.GetMethods())
{
if (!methodInfo.IsStatic)
continue;
Console.Write($"    {(methodInfo.IsStatic ? "static" : "")} {methodInfo.ReturnType} {methodInfo.Name} (");
ParameterInfo[] aParams = methodInfo.GetParameters();
for (int i = 0; i < aParams.Length; i++)
{
ParameterInfo param = aParams[i];
if (i > 0)
Console.Write(", ");
string strRefOrOut;
if (param.ParameterType.IsByRef)
{
if (param.IsOut)
strRefOrOut = "out ";
else
strRefOrOut = "ref ";
}
else
strRefOrOut = "";
Console.Write($"{ strRefOrOut }{ param.ParameterType.ToString() } {param.Name}");
}
Console.WriteLine(");");
}

它生成以下无法编译的源代码:

static System.Void Test1 (System.Collections.Generic.List`1[Employee] employees);
static System.Void Test (System.Collections.Generic.Dictionary`2[System.String, Employee] dict);

我希望它是

static System.Void Test1 (List<Employee> employees);
static System.Void Test (Dictionary<System.String, Employee> dict);

如何从类型中获得所需结果?

我不想做丑陋的事if/else-if/else-if/else";字符串操作来转换它们,因为如果我忘记包含一种类型的集合,那么它就会中断。

是否有一种优雅的方法可以自动获取前者,例如Type.PProperName

如果您不想要Reflection直接提供的内容,那么您需要编写自己的方法来实现您真正想要的内容。这里有一个例子,它将为大多数类型生成C#风格的名称,所以你可以每次调用它并得到正确的结果:

private static string GetTypeName(Type type)
{
var typeName = type.Name;
if (!type.IsGenericType)
{
return typeName;
}
typeName = typeName.Substring(0, typeName.IndexOf('`'));
var parameterTypeNames = type.GetGenericArguments().Select(GetTypeName);
typeName = $"{typeName}<{string.Join(", ", parameterTypeNames)}>";
return typeName;
}

这会忽略名称空间并使用.NET名称,例如";字符串"而不是";字符串";。如果你愿意,你可以改变这些事情。如果确实省略了名称空间,则必须确保也编写了适当的导入。

最新更新