4.5. Fields

Fields maintain the state of an object. Chapter 7 discusses the data types that are allowed for fields. The following field usage guidelines are taken from the Visual Studio help file:

  • Do not use instance fields that are public or protected. If you avoid exposing fields directly to the developer, classes can be versioned more easily because a field cannot be changed to a property while maintaining binary compatibility. Consider providing get and set property accessors for fields instead of making them public. The presence of executable code in get and set property accessors allows later improvements, such as creation of an object on demand, upon usage of the property, or upon a property change notification. The following code example illustrates the correct use of private instance fields with get and set property accessors.

    public struct Point
    {
      private int xValue;
      private int yValue;
    
      public Point(int x, int y)
      {
        this.xValue = x;
        this.yValue = y;
      }
    
      public int X
      {
        get
        {
          return xValue;
        }
        set
        {
          xValue = value;
        }
      }
      public int Y
      {
        get
        {
          return yValue;
        }
        set
        {
          yValue = value;
        }
      }
    }
    
  • Expose a field to a derived class by using a protected property that returns the value of the field. This is illustrated in the following code example.

    public class Control: Component
    {
      private int handle;
      protected int Handle
      {
        get
        {
          return handle;
        }
      }
    }
    
    
  • It is recommended that you use read-only static fields instead of properties where the value is a global constant. This pattern is illustrated in the following code example.

    public struct Int32
    {
      public static readonly int MaxValue = 2147483647;
      public static readonly int MinValue = 2147483648;
      // Insert other members here.
    }
    
  • Spell out all words used in a field name. Use abbreviations only if developers generally understand them. Do not use uppercase letters for field names. The following is an example of correctly named fields.

    class SampleClass
    {
      string url;
      string destinationUrl;
    }
    
  • Do not use Hungarian notation for field names. Good names describe semantics, not type.

  • Do not apply a prefix to field names or static field names. Specifically, do not apply a prefix to a field name to distinguish between static and nonstatic fields. For example, applying a g_ or s_ prefix is incorrect.

  • Use public static read-only fields for predefined object instances. If there are predefined instances of an object, declare them as public static read-only fields of the object itself. Use Pascal case because the fields are public. The following code example illustrates the correct use of public static read-only fields.

    public struct Color
    {
      public static readonly Color Red = new Color (0×0000FF);
      public static readonly Color Green = new Color (0×00FF00);
      public static readonly Color Blue = new Color (0×FF0000);
      public static readonly Color Black = new Color (0×000000);
      public static readonly Color White = new Color (0×FFFFFF);
    
      public Color(int rgb)
      { // Insert code here.}
      public Color(byte r, byte g, byte b)
      { // Insert code here.}
    
      public byte RedValue
      {
        get
        {
          return Color;
        }
      }
      public byte GreenValue
      {
        get
        {
          return Color;
        }
      }
      public byte BlueValue
      {
        get
        {
          return Color;
        }
      }
    }
    

The following keywords are typically used with fields.

4.5.1. public

Public fields, like public methods, are accessible to any class. Use of public static or instance fields is strongly discouraged.

4.5.2. private

Private fields are accessible only to the internal members of a class. Private fields can be defined at the object level (instance) or the class level (static).

4.5.3. protected

Protected fields of a class are accessible to the subclasses of that class.

4.5.4. internal

Internal fields are accessible to classes within the same assembly.

4.5.5. const

The const keyword is used to modify a declaration of a field or local variable. It specifies that neither the value of the field nor the local variable can be modified. A const can be any of the following types: byte, char, short, int, long, float, double, decimal, bool, string, an enum type, or a reference type. The only possible values for constants of reference types are string and null. Fields that are const cannot be static.

Listing 4.13 shows the use of const. Note that multiple declarations of const are allowed, and also a const can be used in an expression.

Listing 4.13. Using the const Keyword (C#)
using System;
public class Test {

  public static void Main(string[] args) {
    const int a = 12;
    const string b = "Jack";
    const int c = a *2;

    Modify (a, b);
    Console.WriteLine(a+" "+b);
    Console.WriteLine(c);
  }
  private static void Modify(int a, string b) {
    a = 4;
    b = "John";
  }
}

Note that the compiler does not complain when we try to assign a value to the constant the second time (in the Modify method). In Java, the standard way to simulate a const is to declare const as final. Although final primitives are similar to the C# const, final object references are not the same as the C# const. In C#, the only valid values for constant references are null and a string literal.

That's not the case with Java. You can declare a final HashMap and have the HashMap() be initialized later in the program, as shown in the following Java snippet. Also note that the Java compiler will complain, unlike C#'s, when you try to reassign a final primitive.

import java.util.HashMap;
public class ConstantTest {
  public static void main(String[] args) {
    final HashMap map = new HashMap();
    map.put("1", "1");
    final int java = 2;
    //java = 3;
    System.out.println(java);
    System.out.println(map);
  }
}

4.5.6. readonly

Fields marked readonly show behavior similar to that of Java final fields. The readonly keyword is a modifier that you can use on fields. When a field declaration includes a readonly modifier, assignments to the fields introduced by the declaration can occur only as part of the declaration or in a constructor in the same class.

You can assign a value to a readonly field only in the following contexts:

  • When the variable is initialized in the declaration—for example:

    public readonly int y = 5;
    
  • For an instance field, in the instance constructors of the class that contains the field declaration; or for a static field, in the static constructor of the class that contains the field declaration. These are also the only contexts in which it is valid to pass a readonly field as an out or ref parameter.

Trying to reassign a readonly field outside the eligible contexts will cause a compiler error similar to that of Java. Listing 4.14 shows the use of readonly fields.

Listing 4.14. Using the readonly Keyword for Fields (C#)
using System;
class Direction {
  int north;
  int south;
  int east;
  int west;
  public Direction (int north, int south, int east, int west) {
      this.north = north;
      this.south = south;
      this.east = east;
      this.west = west;
  }
      public static readonly Direction North;
      public static readonly Direction South;
      public static readonly Direction East;
      public static readonly Direction West;
  static Direction () {
      North = new Direction(1,0,0,0);
      South = new Direction(0,1,0,0);
      East = new Direction(0,0,1,0);
      West = new Direction(0,0,0,1);
  }
  static void Main(string[] args) {
      Direction coor = Direction.North;
  }
}

Note that the readonly fields are initialized in the static constructor.

4.5.7. static

Static fields are applicable to the entire class of objects instead of being local only to the object. In C#, the use of public static fields is strongly discouraged. Instead, public properties should be used (as discussed in Section 4.6).

4.5.8. volatile

The volatile keyword indicates that a field can be modified in the program by something such as the operating system, the hardware, or a concurrently executing thread.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.2.15