字段设计

字段保存对象的关联数据。 在大多数情况下,库中的所有非静态字段对开发人员都应是不可见的。 下面的准则有助于在库设计中正确使用字段。

不要提供公共的或受保护的实例字段。

公共字段和受保护字段未经版本控制,不受代码访问安全性要求的保护。 使用私有字段,并通过属性公开这些私有字段,而不要使用公共可见字段。

对不会更改的常数使用常数字段。

例如,Math 类将 EPI 定义为静态常数。

编译器将 const 字段的值直接插入调用代码中,这意味着任何情况下,const 值都不能更改,可避免引起兼容性问题。

对预定义对象实例使用公共静态只读字段。

例如,DateTime 类提供静态只读字段,使用这些字段可以获取设置为最大或最小时间值的 DateTime 对象。 请参见MaxValueMinValue

不要将可变类型的实例指定给只读字段。

使用可变类型创建的对象可以在创建后进行修改。 例如,数组和大多数集合是可变类型,而 Int32UriString 是不可变类型。 对于保存可变引用类型的字段,只读修饰符可防止字段值被覆盖,但不能防止可变类型被修改。

下面的代码示例演示使用只读字段会出现的问题。 BadDesign 类创建一个只读字段,并使用只读属性公开该字段。 这不能防止 ShowBadDesign 类修改该只读字段的内容。

Imports System

Namespace Examples.DesignGuidelines.Fields

    Public Class BadDesign

        Public Readonly dataValues as Integer() = {1,2,3}

        Public ReadOnly Property Data as Integer ()

            Get 
                Return dataValues
            End Get
        End Property

        Public Sub WriteData()

            For Each i as Integer In dataValues

                Console.Write ("{0} ", i)
            Next i
            Console.WriteLine()
        End Sub
    End Class

    Public Class ShowBadDesign

        Public Shared Sub Main()

            Dim bad as BadDesign = new BadDesign()
            ' The following line will write: 1 2 3
            bad.WriteData()

            Dim badData as Integer() = bad.Data
            For i as Integer  = 0 To badData.Length -1

                badData(i) = 0
            Next i

            ' The following line will write: 0 0 0
            ' because bad's data has been modified.
            bad.WriteData()
        End Sub
    End Class
End Namespace
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();
        }
    }
}
using namespace System;

namespace Examples { namespace DesignGuidelines { namespace Fields
{
    public ref class BadDesign
    {
    public:
        static const array<int>^ data = {1,2,3};

        property array<int>^ Data
        {
            array<int>^ get() {return data;}
        }

        void WriteData()
        {
            for each (int i in data)
            {
                Console::Write ("{0} ", i);
            }
            Console::WriteLine();
        }
    };

    public ref class ShowBadDesign
    {
    public:
        static void Main()
        {
            BadDesign^ bad = gcnew BadDesign();
            // The following line will write: 1 2 3
            bad->WriteData();

            array<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();
        }
    };
}}}

部分版权所有 2005 Microsoft Corporation。 保留所有权利。

部分版权所有 Addison-Wesley Corporation。 保留所有权利。

设计指引的详细信息,请参阅"框架设计准则: 公约、 成语和可重复使用的模式。网络图书馆"书 Krzysztof Cwalina 和布拉德 · 艾布拉姆斯,2005年艾迪生 - 韦斯利,发表。

请参见

其他资源

成员设计准则

类库开发的设计准则