Is there any way to distinguish a non-constant field and a constant field" at compile time in c#?

I am currently developing c# Code Analysis (FxCop) rules to check the developers' code for inconsistency in naming.

What I have been looking for is a way to target only constant fields. But how are they declared when compiled? Is there like a flag (I have been looking into "HasDefault", but this didn't give me much information).

I am using the FxCop-API (FxCopSdk.dll & Microsoft.Cci.dll). No Reflection is used.

Summing up: How can I distinguish a non-constant field from a constant field with Code Analysis(FxCop), and how can I target the constant.

有帮助吗?

解决方案

Researchign further into the FxCop SDK you mentioned, i foudn a field, IsLiteral, which basically means a member which value is specified at compile time.

Would this work for you?

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;
        }
    }

其他提示

If I compile some assembly that contains this class

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

Whatever will not be accesible outside the class. I think, even using reflection. In fact, it may be simplified away in the IL (this is conjecture.)

The name of Whatever is purely a style issue and has no effect on the compiled assembly. If it were a public field, e.g.

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

then the name could be analysed by Code Analysis.


Given that public non-constant fields will already be flagged by

CA1051: Do not declare visible instance fields

CA2211: Non-constant fields should not be visible

perhaps you don't actually need to distinguish at all.

I have found a somewhat dirty way of targeting constants.

Using the following will target them (but may give false-positives):

Field field = member as Field;

if (field == null) 
    return null;
if (field.Flags.HasFlag(FieldFlags.HasDefault) && field.IsLiteral && Field.IsStatic)
{
  // Your code here.
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top