Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在VisualStudio脚手架中获取项目中的所有类_C#_Visual Studio_Envdte - Fatal编程技术网

C# 在VisualStudio脚手架中获取项目中的所有类

C# 在VisualStudio脚手架中获取项目中的所有类,c#,visual-studio,envdte,C#,Visual Studio,Envdte,我正在为VisualStudio构建一个脚手架工具,需要提供一个类列表,这些类派生自某个抽象类,但仅限于活动项目中的类。我已经让它工作了,但是VisualStudio需要一些时间来运行代码 ICodeTypeService codeTypeService = (ICodeTypeService)Context .ServiceProvider.GetService(typeof(ICodeTypeService)); var types = codeTy

我正在为VisualStudio构建一个脚手架工具,需要提供一个类列表,这些类派生自某个抽象类,但仅限于活动项目中的类。我已经让它工作了,但是VisualStudio需要一些时间来运行代码

ICodeTypeService codeTypeService = (ICodeTypeService)Context
                    .ServiceProvider.GetService(typeof(ICodeTypeService));

var types = codeTypeService.GetAllCodeTypes(Context.ActiveProject);

foreach (var type in types)
{
    type.
    if (type.Kind == vsCMElement.vsCMElementClass)
    {
        foreach (var d in type.Bases)
        {
            var dClass = d as CodeClass;
            var name = type.Name;
            if (dClass.Name == "MyAbstractClass")
            {
                if (type.Namespace.Name.Contains(Context.ActiveProject.Name))
                {
                    yield return type.Name;
                }
            }

        }
    }
}
因此,当名称空间找到匹配的类时,我必须检查名称空间,以确保它在我的项目中。这感觉就像我做了很多不必要的工作。这是他们在脚手架模板visual studio项目中给出的示例:

ICodeTypeService codeTypeService = (ICodeTypeService)Context
                    .ServiceProvider.GetService(typeof(ICodeTypeService));

return codeTypeService
    .GetAllCodeTypes(Context.ActiveProject)
    .Where(codeType => codeType.IsValidWebProjectEntityType())
    .Select(codeType => new ModelType(codeType));
codetypeservice是这样做的正确方法吗

编辑
基本上,当它搜索类时,它不仅在当前活动项目中搜索,还搜索所有引用的项目。这就是为什么我必须检查名称空间,以便只从活动项目中获取结果。我想这就是为什么它会慢下来的原因,因为引用的项目非常大,所以它做了大量完全不必要的工作…

我注意到有人对这个问题投了赞成票,提醒我发布我是如何让它工作得更快的。正如Maslow所指出的,Roslyn很酷,但在我构建这个扩展时,Roslyn不可用,除了在预览中,所以基本上它是没有意义的

我的扩展在GitHub上,下面是一个相关的代码片段:

但是万一GitHub死了/有人付我一百万美元买我的代码,这里是相关的代码

/// <summary>
/// Recursively gets all the ProjectItem objects in a list of projectitems from a Project
/// </summary>
/// <param name="projectItems">The project items.</param>
/// <returns></returns>
public IEnumerable<ProjectItem> GetProjectItems(EnvDTE.ProjectItems projectItems)
{
    foreach (EnvDTE.ProjectItem item in projectItems)
    {
        yield return item;

        if (item.SubProject != null)
        {
            foreach (EnvDTE.ProjectItem childItem in GetProjectItems(item.SubProject.ProjectItems))
                yield return childItem;
        }
        else
        {
            foreach (EnvDTE.ProjectItem childItem in GetProjectItems(item.ProjectItems))
                yield return childItem;
        }
    }

}

你能定义“一段时间”吗?你也考虑过罗斯林吗?似乎如果速度是你想要的,那就是最好的选择。在我的机器上大约需要10-15秒,Visual Studio在此期间进入“无响应”模式。所以不可怕,但是…是的。是的,Roslyn看起来确实是未来的发展方向,但这是VS2014的发展方向,对吗?我意识到我并没有很好地解释这个问题…我将在帖子中添加一个编辑,您可以使用
Roslyn
来分析和编写c。另外,Roslyn的部分内容已经在VS2013中了,我知道,我没有意识到这一点。我得调查一下。谢谢你,你帮了我大忙。最后一件事,你有关于Roslyn资源的好链接吗?我发现最好的是Roslyn codeplex,上面有一些例子,应该可以让我继续。再次干杯
var allClasses = GetProjectItems(Context.ActiveProject.ProjectItems).Where(v => v.Name.Contains(".cs"));
// check for .cs extension on each

foreach (var c in allClasses)
{
    var eles = c.FileCodeModel;
    if (eles == null)
        continue;
    foreach (var ele in eles.CodeElements)
    {
        if (ele is EnvDTE.CodeNamespace)
        {
            var ns = ele as EnvDTE.CodeNamespace;
            // run through classes
            foreach (var property in ns.Members)
            {
                var member = property as CodeType;
                if (member == null)
                    continue;

                foreach (var d in member.Bases)
                {
                    var dClass = d as CodeClass;
                    if (dClass == null)
                        continue;

                    var name = member.Name;
                    if (dClass.Name == "DataMigrationImpl")
                    {
                        yield return new Migration(member);
                    }
                }
            }
        }
    }
}