<tfoot id='LZo1J'></tfoot>

    <small id='LZo1J'></small><noframes id='LZo1J'>

    1. <legend id='LZo1J'><style id='LZo1J'><dir id='LZo1J'><q id='LZo1J'></q></dir></style></legend>

      1. <i id='LZo1J'><tr id='LZo1J'><dt id='LZo1J'><q id='LZo1J'><span id='LZo1J'><b id='LZo1J'><form id='LZo1J'><ins id='LZo1J'></ins><ul id='LZo1J'></ul><sub id='LZo1J'></sub></form><legend id='LZo1J'></legend><bdo id='LZo1J'><pre id='LZo1J'><center id='LZo1J'></center></pre></bdo></b><th id='LZo1J'></th></span></q></dt></tr></i><div id='LZo1J'><tfoot id='LZo1J'></tfoot><dl id='LZo1J'><fieldset id='LZo1J'></fieldset></dl></div>
          <bdo id='LZo1J'></bdo><ul id='LZo1J'></ul>
      2. 从 DTE 访问属性信息

        Accessing attribute info from DTE(从 DTE 访问属性信息)

        <tfoot id='GrXHI'></tfoot>

        <small id='GrXHI'></small><noframes id='GrXHI'>

        <i id='GrXHI'><tr id='GrXHI'><dt id='GrXHI'><q id='GrXHI'><span id='GrXHI'><b id='GrXHI'><form id='GrXHI'><ins id='GrXHI'></ins><ul id='GrXHI'></ul><sub id='GrXHI'></sub></form><legend id='GrXHI'></legend><bdo id='GrXHI'><pre id='GrXHI'><center id='GrXHI'></center></pre></bdo></b><th id='GrXHI'></th></span></q></dt></tr></i><div id='GrXHI'><tfoot id='GrXHI'></tfoot><dl id='GrXHI'><fieldset id='GrXHI'></fieldset></dl></div>
        <legend id='GrXHI'><style id='GrXHI'><dir id='GrXHI'><q id='GrXHI'></q></dir></style></legend>

            • <bdo id='GrXHI'></bdo><ul id='GrXHI'></ul>

                    <tbody id='GrXHI'></tbody>
                  本文介绍了从 DTE 访问属性信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我编写了如下代码:

                  [Attrib(typeof(MyCustomType))]
                  public class TargetType
                  {
                    // .....
                  }
                  

                  我想使用 EnvDTE 来获取对 typeof 引用的 CodeElement 的引用.我知道如何获取对属性参数的引用,并且可以使用 Value,但这给了我字符串 typeof(MyCustomType).

                  I want to use EnvDTE to get a reference to the CodeElement referenced by the typeof. I know how to get a reference to the attribute argument, and I can use Value, but that gives me the string typeof(MyCustomType).

                  如果我使用 Value,我必须分解字符串,然后尝试查找类型,如果有两个类型名称相同但名称空间不同,这会变得很麻烦.

                  If I use Value, I have to break down the string and then try to find the type, which gets hairy if there are two types with the same name but different namespaces.

                  有更简单的方法吗?

                  推荐答案

                  有更简单的方法吗?

                  Is there an easier way to do this?

                  不,我不这么认为,至少对于 <= VS2013,似乎 CodeAttributeArgument 没有进一步发展,这很遗憾.他们应该已经发布 CodeAttributeArgument2 具有 Value 作为 CodeExpr :..

                  No, I don't think so, atleast for a <= VS2013, it seems that the CodeAttributeArgument doesn't go any further, which is shame. They should've released CodeAttributeArgument2 that has Value as CodeExpr :..

                  如果您使用 >=VS2014,您可以访问 Roslyn,并且它应该 变得更容易 - 不知道如何在 VS 扩展中访问 roslyn,还得拭目以待.

                  If you use >=VS2014, you can get access to Roslyn, and it should become easier - don't know exactly how you can access roslyn inside VS extension, have to wait and see.

                  为了获取属性,可以使用VS helper:

                  In order to get attributes, you can use VS helper:

                  public List<CodeElement> GetAllCodeElementsOfType(
                      CodeElements elements, 
                      vsCMElement elementType, 
                  
                      bool includeExternalTypes)
                  {
                      var ret = new List<CodeElement>();
                  
                      foreach (CodeElement elem in elements)
                      {
                          // iterate all namespaces (even if they are external)
                          // > they might contain project code
                          if (elem.Kind == vsCMElement.vsCMElementNamespace)
                          {
                              ret.AddRange(
                                  GetAllCodeElementsOfType(
                                      ((CodeNamespace)elem).Members, 
                                      elementType, 
                                      includeExternalTypes));
                          }
                  
                          // if its not a namespace but external
                          // > ignore it
                          else if (elem.InfoLocation == vsCMInfoLocation.vsCMInfoLocationExternal && !includeExternalTypes)
                              continue;
                  
                          // if its from the project
                          // > check its members
                          else if (elem.IsCodeType)
                          {
                              ret.AddRange(
                                  GetAllCodeElementsOfType(
                                      ((CodeType)elem).Members, 
                                      elementType, 
                                      includeExternalTypes));
                          }
                  
                          if (elem.Kind == elementType)
                              ret.Add(elem);
                      }
                      return ret;
                  }
                  

                  原始来源:https://github.com/PombeirP/T4Factories/blob/master/T4Factories.Testbed/CodeTemplates/VisualStudioAutomationHelper.ttinclude

                  与此同时,您可以使用回溯解决方案,这不是很好,但它应该可以工作,还没有完全 100% 测试过.基本思想是从类开始向后跟踪,并跟踪类路径中的不同命名空间/使用.这试图模拟一个真正的编译器会做什么,如果它要解析一个类型:

                  In a meanwhile, you could use backtracking solution, this is not nice, but it should work, haven't tested it exactly 100%. The basic idea is to start tracking backwards from the class, and keep track of different namespaces/usings that arein the path of a class. This tries to simulate pretty much what a real compiler would do, if it's going to resolve a type:

                   var solution = (Solution2) _applicationObject.Solution;
                  var projects = solution.Projects;
                  var activeProject = projects
                      .OfType<Project>()
                      .First();
                  
                  // locate my class.
                  var myClass = GetAllCodeElementsOfType(
                      activeProject.CodeModel.CodeElements,
                      vsCMElement.vsCMElementClass, false)
                      .OfType<CodeClass2>()
                      .First(x => x.Name == "Program");
                  
                  // locate my attribute on class.
                  var mySpecialAttrib = myClass
                      .Attributes
                      .OfType<CodeAttribute2>()
                      .First();
                  
                  
                  
                  var attributeArgument = mySpecialAttrib.Arguments
                      .OfType<CodeAttributeArgument>()
                      .First();
                  
                  string myType = Regex.Replace(
                      attributeArgument.Value, // typeof(MyType)
                      "^typeof.*\((.*)\)$", "$1"); // MyType*/
                  
                  var codeNamespace = myClass.Namespace;
                  var classNamespaces = new List<string>();
                  
                  while (codeNamespace != null)
                  {
                      var codeNs = codeNamespace;
                      var namespaceName = codeNs.FullName;
                  
                      var foundNamespaces = new List<string> {namespaceName};
                  
                      // generate namespaces from usings.
                      var @usings = codeNs.Children
                          .OfType<CodeImport>()
                          .Select(x =>
                              new[]
                              {
                                  x.Namespace,
                                  namespaceName + "." + x.Namespace
                              })
                          .SelectMany(x => x)
                          .ToList();
                  
                      foundNamespaces.AddRange(@usings);
                  
                      // prepend all namespaces:
                      var extra = (
                          from ns2 in classNamespaces
                          from ns1 in @usings
                          select ns1 + "." + ns2)
                          .ToList();
                  
                      classNamespaces.AddRange(foundNamespaces);
                      classNamespaces.AddRange(extra);
                  
                      codeNamespace = codeNs.Parent as CodeNamespace;
                      if (codeNamespace == null)
                      {
                          var codeModel = codeNs.Parent as FileCodeModel2;
                          if (codeModel == null) return;
                  
                          var elems = codeModel.CodeElements;
                          if (elems == null) continue;
                  
                          var @extraUsings = elems
                              .OfType<CodeImport>()
                              .Select(x => x.Namespace);
                  
                          classNamespaces.AddRange(@extraUsings);
                      }
                  }
                  
                  // resolve to a type!
                  var typeLocator = new EnvDTETypeLocator();
                  var resolvedType = classNamespaces.Select(type =>
                          typeLocator.FindTypeExactMatch(activeProject, type + "." + myType))
                      .FirstOrDefault(type => type != null);
                  

                  您还需要 EnvDTETypeLocator.

                  对于 VS2015,可以从此处找到 roslyn 集成的示例:https://github.com/tomasr/roslyn-colorizer/blob/master/RoslynColorizer/RoslynColorizer.cs

                  For VS2015, an example of roslyn integration can be found from here: https://github.com/tomasr/roslyn-colorizer/blob/master/RoslynColorizer/RoslynColorizer.cs

                  肯定会比使用当前的 CodeModel 容易得多.

                  It'll definitely be A lot easier than it is with current CodeModel.

                  这篇关于从 DTE 访问属性信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  Performance overhead of using attributes in .NET(在 .NET 中使用属性的性能开销)
                  c# Hide a property in datagridview with datasource(c#使用数据源隐藏datagridview中的属性)
                  Extract Display name and description Attribute from within a HTML helper(从 HTML 帮助器中提取显示名称和描述属性)
                  How can I force the PropertyGrid to show a custom dialog for a specific property?(如何强制 PropertyGrid 显示特定属性的自定义对话框?)
                  Associate attribute with code generated property in .net(将属性与 .net 中的代码生成属性相关联)
                  C# Attributes and their uses(C# 属性及其用途)
                  <legend id='j3PRL'><style id='j3PRL'><dir id='j3PRL'><q id='j3PRL'></q></dir></style></legend>
                      <tbody id='j3PRL'></tbody>
                      <bdo id='j3PRL'></bdo><ul id='j3PRL'></ul>

                        <i id='j3PRL'><tr id='j3PRL'><dt id='j3PRL'><q id='j3PRL'><span id='j3PRL'><b id='j3PRL'><form id='j3PRL'><ins id='j3PRL'></ins><ul id='j3PRL'></ul><sub id='j3PRL'></sub></form><legend id='j3PRL'></legend><bdo id='j3PRL'><pre id='j3PRL'><center id='j3PRL'></center></pre></bdo></b><th id='j3PRL'></th></span></q></dt></tr></i><div id='j3PRL'><tfoot id='j3PRL'></tfoot><dl id='j3PRL'><fieldset id='j3PRL'></fieldset></dl></div>

                        <small id='j3PRL'></small><noframes id='j3PRL'>

                        1. <tfoot id='j3PRL'></tfoot>