簡體   English   中英

如何在自定義FxCop規則中檢測自動實現的屬性?

[英]How to detect an auto-implemented property in a custom FxCop rule?

我正在嘗試為DTO編寫一個規則,它只允許自動實現的屬性。 如何使用FxCop API檢測到屬性是自動實現的?

實際上,用戶在IL編譯代碼中實現的自動屬性和屬性之間存在差異。 自動屬性設置器和getter使用System.Runtime.CompilerServices.CompilerGeneratedAttribute標記。

自動屬性編譯IL代碼

因此,使用NDepend工具, 您可以通過C#LINQ查詢編寫自定義代碼查詢和自定義代碼規則 ,匹配自動屬性getter和setter只需編寫LINQ查詢:

from m in Application.Methods
where (m.IsPropertyGetter|| m.IsPropertySetter)
    && m.IsGeneratedByCompiler
select m

NDepend自動屬性代碼查詢匹配

請注意,在上面的屏幕截圖中,您可能會在Resources生成的類中匹配getter和setter,為了防止這種情況,您可以添加像&& !m.ParentType.IsUsing("System.Resources.ResourceManager")這樣的子句:

NDepend自動屬性代碼查詢匹配,無需資源匹配

當然,所有這些都可以適應FxCop定制裁決系統。

免責聲明:我為NDepend工作

謝謝NDepend團隊的@Patrick。 這是生成的FxCop規則的代碼。

using Microsoft.FxCop.Sdk;
using System.Linq;
using System.Runtime.CompilerServices;

namespace CustomFxRules
{
    internal sealed class IsAutoImplementedProperty : BaseIntrospectionRule
    {
        public IsAutoImplementedProperty()
            : base("IsAutoImplementedProperty", "CustomFxRules.CustomFxRules", typeof(IsAutoImplementedProperty).Assembly)
        {
        }

        public override TargetVisibilities TargetVisibility
        {
            get { return TargetVisibilities.ExternallyVisible; }
        }

        private TypeNode CompilerGeneratedAttributeType { get; set; }

        public override void BeforeAnalysis()
        {
            base.BeforeAnalysis();

            this.CompilerGeneratedAttributeType = FrameworkAssemblies.Mscorlib.GetType(
                Identifier.For("System.Reflection"),
                Identifier.For("CompilerGeneratedAttribute"));
        }

        public override ProblemCollection Check(Member member)
        {
            if (member.NodeType != NodeType.Property)
                return base.Check(member);

            var property = (PropertyNode)member;
            VisitProperty(property);
            return this.Problems;
        }

        private const string AddAutoImplementedPropertyResolutionName = "Add auto-implemented property";

        public override void VisitProperty(PropertyNode property)
        {
            if (property.Getter == null)
            {
                Problems.Add(new Problem(new Resolution(AddAutoImplementedPropertyResolutionName, "{0} property must have a getter", property.FullName)));
            }
            else if (property.Getter.Attributes.All(attributeNode => attributeNode.Type.FullName != typeof(CompilerGeneratedAttribute).FullName))
            {
                Problems.Add(new Problem(new Resolution(AddAutoImplementedPropertyResolutionName, "{0} property must have an auto-impelemented getter", property.FullName)));
            }

            if (property.Setter == null)
            {
                Problems.Add(new Problem(new Resolution(AddAutoImplementedPropertyResolutionName, "{0} property must have a setter", property.FullName)));
            }
            else if (property.Setter.Attributes.All(attributeNode => attributeNode.Type.FullName != typeof(CompilerGeneratedAttribute).FullName))
            {
                Problems.Add(new Problem(new Resolution(AddAutoImplementedPropertyResolutionName, "{0} property must have an auto-impelemented setter", property.FullName)));
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM