codeformatter icon indicating copy to clipboard operation
codeformatter copied to clipboard

Should convert "static readonly" field to Pascal style?

Open AllenLius opened this issue 7 years ago • 13 comments

A "static readonly" field more like a const field that can be changed only in static ctor.

AllenLius avatar Nov 23 '18 11:11 AllenLius

Yes

lindexi avatar Nov 28 '18 12:11 lindexi

Yes

But I see the "static readonly" fields is converted to camel style with '_' prefix: "static readonly Dictionary<string, int> _captureIndex".

AllenLius avatar Nov 28 '18 12:11 AllenLius

public static fields should be PascalCased. internal and private static fields should be s_camelCased with the "s_" prefix.

stephentoub avatar Nov 28 '18 13:11 stephentoub

public static fields should be PascalCased. internal and private static fields should be s_camelCased with the "s_" prefix.

And I think "static readonly" should be PascalCased too instead of _camelCased in current behavior of the tool.

AllenLius avatar Nov 28 '18 13:11 AllenLius

And I think "static readonly" should be PascalCased too instead of _camelCased in current behavior of the tool.

I don't know what the current behavior of the tool is, but readonly should not influence the naming, at least as far as our style in corefx is concerned.

stephentoub avatar Nov 28 '18 13:11 stephentoub

I don't know what the current behavior of the tool is, but readonly should not influence the naming, at least as far as our style in corefx is concerned.

For rule "12: We use PascalCasing to name all our constant local variables and fields". A static readonly field just like a special const field that can be initialized inline or in the constructor method only, so I think we should use Pascal rule too.

AllenLius avatar Nov 28 '18 13:11 AllenLius

A static readonly field just like a special const field that can be initialized inline or in the constructor method only, so I think we should use Pascal rule too.

No, there's a difference between consts and static readonlys, and we have different naming rules for them.

stephentoub avatar Nov 28 '18 13:11 stephentoub

@stephentoub as the style say it doesn't matter if you use or not to use an underline and whether it is public or not.

lindexi avatar Nov 29 '18 07:11 lindexi

@lindexi I'm not sure I follow.

  1. We use _camelCase for internal and private fields and use readonly where possible. Prefix internal and private instance fields with _, static fields with s_ and thread static fields with t_. When used on static fields, readonly should come after static (e.g. static readonly not readonly static). Public fields should be used sparingly and should use PascalCasing with no prefix when used.

This means the naming rules are:

  • private Foo _foo;
  • private static Foo s_foo;
  • [ThreadStatic] private static Foo t_foo;
  • private readonly Foo _foo = InitializeFoo();
  • private static readonly Foo s_foo = InitializeFoo();
  • public Foo Foo;
  • public static Foo Foo;
  • [ThreadStatic] public static Foo Foo;
    • This can only go poorly :smile:.
  • public readonly Foo Foo = InitializeFoo();
  • public static readonly Foo Foo = InitializeFoo();

The readonly-ness doesn't change the casing style or prefixes. public is what does.

While static readonly int is vaguely const-ish, static readonly Dictionary<A,B> isn't; readonly means "may not be reassigned after the constructor", which is not the same as C# const, C const or an immutable concept.

And we definitely wouldn't call private static readonly object s_lock = new object(); const, but it better be readonly, since reassignment would break anything locking on it.

bartonjs avatar Nov 29 '18 07:11 bartonjs

@lindexi I'm not sure I follow.

  1. We use _camelCase for internal and private fields and use readonly where possible. Prefix internal and private instance fields with _, static fields with s_ and thread static fields with t_. When used on static fields, readonly should come after static (e.g. static readonly not readonly static). Public fields should be used sparingly and should use PascalCasing with no prefix when used.

This means the naming rules are:

  • private Foo _foo;

  • private static Foo s_foo;

  • [ThreadStatic] private static Foo t_foo;

  • private readonly Foo _foo = InitializeFoo();

  • private static readonly Foo s_foo = InitializeFoo();

  • public Foo Foo;

  • public static Foo Foo;

  • [ThreadStatic] public static Foo Foo;

    • This can only go poorly 😄.
  • public readonly Foo Foo = InitializeFoo();

  • public static readonly Foo Foo = InitializeFoo();

The readonly-ness doesn't change the casing style or prefixes. public is what does.

While static readonly int is vaguely const-ish, static readonly Dictionary<A,B> isn't; readonly means "may not be reassigned after the constructor", which is not the same as C# const, C const or an immutable concept.

And we definitely wouldn't call private static readonly object s_lock = new object(); const, but it better be readonly, since reassignment would break anything locking on it.

You are right, the readonly doesn't influence the name style.

An exception is that the private const field should be in PascalCased: private const int Port = 80; I think it is just a little tricky if we what to read the port from a config file instead: private static readonly int s_port = GetHttpPort(); then we need to update the name in code.

AllenLius avatar Nov 29 '18 08:11 AllenLius

@AllenLius But I think the const int and static readonly has the same means.

lindexi avatar Nov 29 '18 08:11 lindexi

@AllenLius But I think the const int and static readonly has the same means. Yes, I'm on your side, the means for a dev is just the same: initialized once and should not be changed after that. but the codeformatter is just follow the coding style of the donetcore.

AllenLius avatar Nov 29 '18 09:11 AllenLius

const values are replaced by the compiler with their constant value, so if you look at generated output IL you'd see the literal 80.

static readonly means there's still a field-read. If a debugger, or unsafe code, changed the static field value, that would have a runtime effect on all places that read it.

A subtle difference, but a difference nonetheless.

bartonjs avatar Nov 29 '18 09:11 bartonjs