学习笔记:C#中字段和属性的区别

C#语言规范5.0中对字段的解释:

1.6.5 字段

字段是与类或类的实例关联的变量。

使用 static 修饰符声明的字段定义了一个静态字段 (static field)。一个静态字段只标识一个存储位置。无论对一个类创建多少个实例,它的静态字段永远都只有一个副本。

不使用 static 修饰符声明的字段定义了一个实例字段 (instance field)。类的每个实例都为该类的所有实例字段包含一个单独副本。

在下面的示例中,Color 类的每个实例都有实例字段 r、g 和 b 的单独副本,但是 Black、White、Red、Green 和 Blue 静态字段只存在一个副本:

public class Color
{
public static readonly Color Black = new Color(0, 0, 0);
public static readonly Color White = new Color(255, 255, 255);
public static readonly Color Red = new Color(255, 0, 0);
public static readonly Color Green = new Color(0, 255, 0);
public static readonly Color Blue = new Color(0, 0, 255);

private byte r, g, b;

public Color(byte r, byte g, byte b) {
     this.r = r;
     this.g = g;
     this.b = b;
}
}

如上面的示例所示,可以使用 readonly 修饰符声明只读字段 (read-only field)。给 readonly 字段的赋值只能作为字段声明的组成部分出现,或在同一个类中的构造函数中出现。

1.6.7.2 属性

属性 (property) 是字段的自然扩展。

属性和字段都是命名的成员,都具有相关的类型,且用于访问字段和属性的语法也相同。然而,与字段不同,属性不表示存储位置。相反,属性有访问器 (accessor),这些访问器指定在它们的值被读取或写入时需执行的语句。

属性的声明与字段类似,不同的是属性声明以位于定界符 { 和 } 之间的一个 get 访问器和/或一个 set 访问器结束,而不是以分号结束。同时具有 get 访问器和 set 访问器的属性是读写属性 (read-write property),只有 get 访问器的属性是只读属性 (read-only property),只有 set 访问器的属性是只写属性 (write-only property)。

get 访问器相当于一个具有属性类型返回值的无形参方法。除了作为赋值的目标,当在表达式中引用属性时,将调用该属性的 get 访问器以计算该属性的值。

set 访问器相当于具有一个名为 value 的参数并且没有返回类型的方法。当某个属性作为赋值的目标被引用,或者作为 ++ 或 -- 的操作数被引用时,将调用 set 访问器,并传入提供新值的实参。

List<T> 类声明了两个属性 Count和 Capacity,它们分别是只读属性和读写属性。下面是这些属性的使用示例。

List<string> names = new List<string>();
names.Capacity = 100;        // Invokes set accessor
int i = names.Count;            // Invokes get accessor
int j = names.Capacity;         // Invokes get accessor

与字段和方法相似,C# 同时支持实例属性和静态属性。静态属性使用 static 修饰符声明,而实例属性的声明不带该修饰符。

属性的访问器可以是虚的。当属性声明包括 virtual、abstract 或 override 修饰符时,修饰符应用于该属性的访问器。

————————————————————————————

字段与属性的区别

在C#中,我们可以非常自由的、毫无限制的访问公有字段,但在一些场合中,我们可能希望限制只能给字段赋于某个范围的值、或是要求字段只能读或只能写,或是在改变字段时能改变对象的其他一些状态,这些单靠字段是无法做到的,于是就有了属性,属性中包含两个块:set和get,set块负责属性的写入工作,get块负责属性的读取工作。在两个块中都可以做一些其他操作,如在set中验证赋的值是否符合要求并决定是否进行赋值。当缺少其中一块时属性就只能读或只能写,set和get块中属性必需有一个,因为即不能读又不能写的属性是没有意义的。

class MyClass

{

       Private  string  name;

 public string Name

 {

  get {return Name;}

  set {Name=value;}

 }

}

(1)属性可以保证安全,当不在本类中使用时可以保证使用属性名可以避免

用字段的名字。

 (2)属性的set和get函数可以限制字段的一些功能,以达到某种目的。

 如: 




private int a=0;

public int A

{

     get{return this.a;}

     set

     {

         if(value >= 0 && value <= 100)

              this.a=value;

         else

              throw new Exception("值的范围不合法。");

     }

}

(3)属性没有存储数据的功能,数据都存在字段中,所以只有修改字段的数据才能更改数据,修改属性的值没用。

 

------------------------------------

字段与属性的使用

一般情况下,是先定义字段,再用属性控制赋值的范围。示例代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Example3_2
{
    public class Person     //定义Person类
    {
        public string Name { get; set; }    //
    }
    public class Student
    {
        //public string Name { get; set; }
        //public int Age { get; set; }

        //姓名
        string name;
        public string Name
        {
            get { return this.name; }
            set
            {
                if (value == "")
                {
                    throw new ArgumentException("姓名不能为空字符串。");
                }
                this.name = value;
            }
        }
        //年龄
        private int age;
        public int Age
        {
            get { return this.age; }
            set
            {
                if (value < 1 || value > 100)
                {
                    throw new ArgumentException("年龄超出了有效范围。");
                }
                this.age = value;
            }
        }
    }
        class Program
        {
            static void Main(string[] args)
            {
                Student stu = new Student();
                stu.Name = "章三";
                stu.Age = 56;
                            
                Console.WriteLine("姓名是:{0}", stu.Name);
                Console.WriteLine("年龄是:{0}", stu.Age);
                Console.ReadKey();
            }
        }
    
}

运行结果如下:

如果属性只不需要特殊验证处理,可以使用简化的属性声明语法。直接写属性,不写字段。

例如:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Example3_2
{
    public class Person     //定义Person类
    {
        public string Name { get; set; }    //
    }
    public class Student
    {
        public string Name { get; set; }
        public int Age { get; set; }
        
    }
        class Program
        {
            static void Main(string[] args)
            {
                Student stu = new Student();
                stu.Name = "章三";
                stu.Age = 56;
                            
                Console.WriteLine("姓名是:{0}", stu.Name);
                Console.WriteLine("年龄是:{0}", stu.Age);
                Console.ReadKey();
            }
        }
    
}

运行结果相同。

发布了35 篇原创文章 · 获赞 1 · 访问量 835

猜你喜欢

转载自blog.csdn.net/qq_41708281/article/details/104231353