我们正在使用Visual Studio CodeModel并且在获取CodeType的泛型参数时遇到一些问题。如何在不解析FullName
的情况下获取它们?
在How can I get the generic constraints from CodeInterface as a CodeType object?中暗示(虽然没有标记答案)没有其他办法,但是,这并不是真正可信的:
System.Func<Outer.Inner>
将无法定义:您无法知道您已解析的通用参数(Outer.Inner
)是否指的是包含类Outer
的命名空间Inner
,或者它是否指的是具有内部类Outer
的类Inner
(是的,在这种情况下,它不是Outer+Inner
。
如果有人至少知道如何告诉FullName属性显示带有+
符号的嵌套类,那么这也很棒。
答案 0 :(得分:0)
我认为answer here非常明确。这不受DTE或DTE2的支持,将来不太可能得到支持。
目前唯一的方法是使用Roslyn,这对我们这些不想使用预发布软件的人来说是不可接受的。我还没有研究过哪种类型的依赖项(我的组件用户需要安装Roslyn吗?)。
你可以使用正则表达式从FullName字符串中获取类型。但是,对于我们这些需要令牌(T
)到具体类型(System.String
)映射的现实世界中的人来说,这不是一种选择。
答案 1 :(得分:0)
我无法找到任何通用类型的方法,但如果您需要针对特定类型执行此操作,则在某些情况下可能会这样做。
例如,我有以下代码来检查类型是否是一个集合,如果是,则获取元素类型:
private static bool IsCollectionType(CodeType type, out CodeType elementType)
{
// string implements IEnumerable<char>, but we don't want to treat it as a collection
if (type.FullName == "System.String")
{
elementType = null;
return false;
}
var enumerable = type.Bases.OfType<CodeInterface>().FirstOrDefault(i => i.FullName.StartsWith("System.Collections.Generic.IEnumerable<"));
var method = enumerable?.Members.OfType<CodeFunction>().FirstOrDefault(m => m.Name == "GetEnumerator");
var enumerator = method?.Type.CodeType;
var current = enumerator?.Members.OfType<CodeProperty>().FirstOrDefault(m => m.Name == "Current");
if (current != null)
{
elementType = current.Type.CodeType;
return true;
}
elementType = null;
return false;
}
正如您所看到的,我并未直接查看泛型类型参数,而是查看IEnumerable<T>.GetEnumerator().Current
的类型。当然,这需要具体了解您正在使用的类型。