locked
Custom Rule: accessing static readonly field initial value

    Question

  • Hello,

    I need to create custom rule to check initial values (!) of fields.
    Those fields are const or static readonly, for example:

    public class foo
    {
        public const string Const1 = "sth";
        public static readonly string Imm1 = "sth";
    ..
    }

    I can easily access const fields values:

    Field field = member as Field;

    if (field != null && field.IsLiteral)

    {

    //test

    Problems.Add(new Problem(new Resolution(string.Format("const {0} = {1}", field.Name.Name, field.DefaultValue.Value))));

    }


    but have no idea how to get value of static readonly. Neither Field.Initializer nor Field.InitalData property works.
    Looking fwd for some help,
    Thanks

    n
    Thursday, January 15, 2009 5:32 PM

Answers

  • Hi there,

    It seems that I found an answer on my own:

    .method private hidebysig specialname rtspecialname static
            void  .cctor() cil managed
    {
      // Code size       21 (0x15)
      .maxstack  8
      IL_0000:  ldstr      "static readonly"
      IL_0005:  stsfld     string StringField.Class1::fldStaticRO
      IL_000a:  ldstr      "static"
      IL_000f:  stsfld     string StringField.Class1::fldStatic
      IL_0014:  ret
    } // end of method Class1::.cctor

    .method public hidebysig specialname rtspecialname
            instance void  .ctor() cil managed
    {
      // Code size       7 (0x7)
      .maxstack  8
      IL_0000:  ldarg.0
      IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
      IL_0006:  ret
    } // end of method Class1::.ctor

    IL code of example above shows that readonly field initialized inline is handled in the same way as ordinary field. Here it is done in implicit static constructor (.cctor) because all fields are static. So what I need to do is to search .cctor operations for ldstr - stsfld pairs for initonly fields
    (see http://social.msdn.microsoft.com/Forums/en-US/vstscode/thread/750b5a43-2755-497a-a31f-f782db89c6a8/)

    BR,

    n

    • Marked as answer by nijuniro Thursday, January 22, 2009 11:11 AM
    Thursday, January 22, 2009 11:10 AM

All replies

  • Hello nijuniro,

    Have you found a solution already?

    Could you please try the following code and tell me the result?

    if (field.IsStatic && field.IsInitOnly)  
    {  
        Problems.Add(new Problem(this.GetResolution()));  

    Best regards,
    Roahn
    Tuesday, January 20, 2009 2:28 PM
  • Hello Roahn,

    Thanks for answer. No solution so far.

    I've tried your code - it works fine but it 's still not what I want to achieve:
    - it detects readonly static fields, that are initialized inline
    - I need to obtain initial values of such fields

    For example:

    - analyzed class

    public const string fldConst = "const";

    public static readonly string fldStaticRO = "static readonly";

    public static string fldStatic = "static";


    - rules

    if (field.IsLiteral)

    {

    Problems.Add(new Problem(new Resolution(string.Format("const {0} = {1}", field.Name.Name, field.DefaultValue.Value))));

    }

    if (field.IsStatic)

    {

    Problems.Add(new Problem(new Resolution(string.Format("static {0} = {1}", field.Name.Name, "no idea?"))));

    }

    if (field.IsStatic && field.IsInitOnly)

    {

    Problems.Add(new Problem(new Resolution(string.Format("static (init only) {0} = {1}", field.Name.Name, "no idea?"))));

    }

    - FxCop output

    <Location not stored in Pdb> : warning PR0000 : PrimaRules : const fldConst = const
    <Location not stored in Pdb> : warning PR0000 : PrimaRules : static fldConst = no idea?
    <Location not stored in Pdb> : warning PR0000 : PrimaRules : static fldStatic = no idea?
    <Location not stored in Pdb> : warning PR0000 : PrimaRules : static (init only) fldStaticRO = no idea?
    <Location not stored in Pdb> : warning PR0000 : PrimaRules : static fldStaticRO = no idea?

    Result shows that I can filter:
    - const fields using IsLiteral property
    - readonly static field using IsStatic and IsInitOnly properties (just as you suggested)

    But field.DefaultValue is null for readonly static field.
    All I need is that value, any clue?

    Best regards,

    n

    Wednesday, January 21, 2009 12:48 PM
  • Hi there,

    It seems that I found an answer on my own:

    .method private hidebysig specialname rtspecialname static
            void  .cctor() cil managed
    {
      // Code size       21 (0x15)
      .maxstack  8
      IL_0000:  ldstr      "static readonly"
      IL_0005:  stsfld     string StringField.Class1::fldStaticRO
      IL_000a:  ldstr      "static"
      IL_000f:  stsfld     string StringField.Class1::fldStatic
      IL_0014:  ret
    } // end of method Class1::.cctor

    .method public hidebysig specialname rtspecialname
            instance void  .ctor() cil managed
    {
      // Code size       7 (0x7)
      .maxstack  8
      IL_0000:  ldarg.0
      IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
      IL_0006:  ret
    } // end of method Class1::.ctor

    IL code of example above shows that readonly field initialized inline is handled in the same way as ordinary field. Here it is done in implicit static constructor (.cctor) because all fields are static. So what I need to do is to search .cctor operations for ldstr - stsfld pairs for initonly fields
    (see http://social.msdn.microsoft.com/Forums/en-US/vstscode/thread/750b5a43-2755-497a-a31f-f782db89c6a8/)

    BR,

    n

    • Marked as answer by nijuniro Thursday, January 22, 2009 11:11 AM
    Thursday, January 22, 2009 11:10 AM