7

我们正在使用 Visual Studio CodeModel,并且在获取 CodeType 的通用参数时遇到了一些问题。如何在不解析FullName自己的情况下获得它们?

How can I get the generic constraint from CodeInterface as a CodeType object?没有其他方法,但是,这并不可信,因为:

System.Func<Outer.Inner>

不会被定义:你不知道你解析的泛型参数 ( Outer.Inner) 是指Outer包含类的命名空间Inner,还是指Outer具有内部类的类Inner(是的,在这种情况下不是Outer+Inner)。

如果有人至少知道如何告诉 FullName 属性以显示带有+符号的嵌套类,那也很棒。

4

2 回答 2

0

我认为这里的答案是非常确定的。DTE 或 DTE2 不支持此功能,将来也不太可能支持。

目前唯一的方法是使用 Roslyn,这对于我们这些不想使用预发布软件的人来说是不可接受的。我还没有研究将需要什么样的依赖项(我的组件的用户是否需要安装 Roslyn?)。

可以使用正则表达式从 FullName 字符串中获取类型。但是,对于我们这些现实世界中需要令牌 ( T) 到具体类型 ( System.String) 映射的人来说,这不是一种选择。

于 2014-11-23T10:57:30.100 回答
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. 当然,这需要有关您正在使用的类型的特定知识。

于 2017-10-18T16:28:12.133 回答