编译时的常量字段

本文关键字:字段 常量 编译 | 更新日期: 2023-09-27 17:57:37

有没有办法在c#中的编译时区分非常数字段和常数字段?

我目前正在开发c#代码分析(FxCop)规则,以检查开发人员的代码在命名方面的不一致性。

我一直在寻找一种只针对恒定场的方法。但是它们在编译时是如何声明的呢?是否有类似的标志(我一直在研究"HasDefault",但这并没有给我太多信息)。

我正在使用FxCop-API(FxCopSdk.dll和Microsoft.Cci.dll)。未使用反射。

总结:如何使用代码分析(FxCop)区分非常量字段和常量字段,以及如何针对常量。

编译时的常量字段

深入研究您提到的FxCop SDK,我创建了一个字段IsLiteral,它基本上意味着在编译时指定值的成员。

这对你有用吗?

E.g

    public class ClassFieldNamePrefixes : BaseIntrospectionRule
    {
        public ClassFieldNamePrefixes() :
            base("ClassFieldNamePrefixes", "TutorialRules.TutorialRules",
                typeof (ClassFieldNamePrefixes).Assembly)
        {
        }
        public override ProblemCollection Check(Member member)
        {
            if (!(member.DeclaringType is ClassNode))
                return this.Problems;
            Field fld = member as Field;
            if (fld == null)
                return this.Problems;
            if (fld.IsLiteral && 
                fld.IsStatic && 
                field.Flags.HasFlag(FieldFlags.HasDefault))
            {
            ....
            }
            return this.Problems;
        }
    }

如果我编译了包含此类的某个程序集

namespace Foo
{
    public static class Bar
    {
        public int Pointless()
        {
            const int Whatever = 1;
            return Whatever;  
        }
    }
}

Whatever在类之外将不可访问。我想,甚至用反射。事实上,它可能会在IL中被简化(这是猜测)

Whatever的名称纯粹是一个样式问题,对已编译的程序集没有任何影响。如果是public字段,例如

namespace Foo
{
    public static class Bar
    {
        public const int Whatever = 1;
    }
}

则可以通过代码分析来分析该名称。


考虑到公共非常量字段已经被标记

CA1051:不声明可见实例字段

CA2211:非恒定字段不应为可见

也许你实际上根本不需要区分。

我发现了一种针对常量的肮脏方法。

使用以下方法将针对他们(但可能会出现误报):

Field field = member as Field;
if (field == null) 
    return null;
if (field.Flags.HasFlag(FieldFlags.HasDefault) && field.IsLiteral && Field.IsStatic)
{
  // Your code here.
}