Export (0) Print
Expand All
2 out of 2 rated this helpful - Rate this topic

Field Design

Fields hold data associated with an object. In the vast majority of scenarios any non-static fields in a library should not be visible to developers. The following guidelines help you correctly use fields in your library design.

Do not provide instance fields that are public or protected.

Public and protected fields do not version well and are not protected by code access security demands. Instead of using publicly visible fields, use private fields and expose them through properties.

Do use constant fields for constants that will never change.

For example, the Math class defines E and PI as static constants.

The compiler inserts the values of const fields directly into the calling code, which means that const values can never be changed without the risk of introducing a compatibility issue.

Do use public static read-only fields for predefined object instances.

For example, the DateTime class provides static read-only fields that you can use to obtain DateTime objects set to the maximum or minimal time value. See MaxValue and MinValue.

Do not assign instances of mutable types to read-only fields.

The objects created using a mutable type can be modified after they are created. For example, arrays and most collections are mutable types while Int32, Uri, and String are immutable types. For fields that hold a mutable reference type, the read-only modifier prevents the field value from being overwritten but does not protect the mutable type from modification.

The following code example demonstrates the problem with using read-only fields. The BadDesign class creates a read-only field and exposes it using a read-only property. This does not prevent the ShowBadDesign class from modifying the contents of the read-only field.


using System;

namespace Examples.DesignGuidelines.Fields
{
    public class BadDesign
    {
        public readonly int[] data = {1,2,3};

        public int [] Data
        {
            get {return data;}
        }
        public void WriteData()
        {
            foreach (int i in data)
            {
                Console.Write ("{0} ", i);
            }
            Console.WriteLine();
        }
    }
    public class ShowBadDesign
    {
        public static void Main()
        {
            BadDesign bad = new BadDesign();
            // The following line will write: 1 2 3
            bad.WriteData();

            int[] badData = bad.Data;
            for (int i = 0; i< badData.Length; i++)
            {
                badData[i] = 0;
            }
            // The following line will write: 0 0 0
            // because bad's data has been modified.
            bad.WriteData();
        }
    }
}


Portions Copyright 2005 Microsoft Corporation. All rights reserved.

Portions Copyright Addison-Wesley Corporation. All rights reserved.

For more information on design guidelines, see the "Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries" book by Krzysztof Cwalina and Brad Abrams, published by Addison-Wesley, 2005.

Did you find this helpful?
(1500 characters remaining)
Thank you for your feedback

Community Additions

ADD
Show:
© 2014 Microsoft. All rights reserved.