How get Attribute Value in CodeAttribute

社会主义新天地 提交于 2020-05-29 03:52:21

问题


I wrote a method to get Attribute Value By Property:

public string GetAttributeValueByNameAttributeAndProperty(CodeClass cc, string nameAttribute, string nameProperty)
{
    var value = "";
    foreach(CodeAttribute ca in cc.Attributes) 
            { 
                if(ca.Name.Contains(nameAttribute) && ca.Value.Contains(nameProperty))
                {
                    value = ca.Value.Remove(0,ca.Value.IndexOf(nameProperty));
                    value = value.Replace(" ","");
                    if(value.Contains(","))
                        value = value.Remove(ca.Value.IndexOf(","));
                }
            }

     return value;
}

For Example: I have Attribute [Map(Name = "MenuItem, Availability" )]

I call GetAttributeValueByNameAttributeAndProperty( codeclass, "Map" , "Name") After that method get CodeAttribute.Value and return string: Name = "MenuItem, Availability" After I remove "Name = " and extra characters and Split by ","

But my Senior Programmer told me that this method is inflexible and I need to find a more convenient way get inner data in CodeAttribute.Value.

Do you have any ideas / examples?


回答1:


You can use CodeClass.Attributes property to get attributes of a class. Each attribute is of type of CodeAttribute and has a Name and a Children property which contains arguments of the attribute. Each argument is of type of CodeAttributeArgument which has Name and Value properties.

Example

Now you have all information which you need to get attribute value from CodeAttribute. Here is an example. I've decorated Program class with a [MySample(Property1 = "Something")] attribute

using System;
namespace ConsoleSample
{
    [MySample(Property1 = "Something")]
    class Program
    {
        static void Main(string[] args)
        {
        }
    }
    public class MySampleAttribute : Attribute
    {
        public string Property1 { get; set; }
    }
}

And here is the sample T4 template:

<#@ template debug="true" hostSpecific="true" #>
<#@ output extension=".txt" #>
<#@ assembly Name="System.Core" #>
<#@ assembly name="EnvDte" #>
<#@ assembly name="EnvDte80" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Collections.Generic" #> 
<#@ import namespace="EnvDTE" #> 
<#@ import namespace="EnvDTE80" #> 
<#    
var env = (this.Host as IServiceProvider).GetService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
var project = env.Solution.FindProjectItem(this.Host.TemplateFile).ContainingProject
    as EnvDTE.Project;
var codeClass = project.ProjectItems.Item("Program.cs").FileCodeModel.CodeElements
                       .OfType<CodeNamespace>().ToList()[0]
                       .Members.OfType<CodeClass>().ToList()[0];
var attribute = codeClass.Attributes.Cast<CodeAttribute>()
                         .Where(a=>a.Name=="MySample").FirstOrDefault();
if(attribute!=null)
{
    var property = attribute.Children.OfType<CodeAttributeArgument>()
                            .Where(a=>a.Name=="Property1").FirstOrDefault();
    if(property!=null)
    {
        var value = property.Value;
        WriteLine(value);
    }
}
#>

If you run the template, you will receive "Something" in output.



来源:https://stackoverflow.com/questions/29945235/how-get-attribute-value-in-codeattribute

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!