C#中真正的属性

引言

我们以前课堂上说的类当中的“属性”,其实官方叫法是“字段”或者“域”域(Field)。正常使用,把它们当属性理解更加方便快捷,也没有什么问题。

如果要在微软的mvc中充分利用类带来的便利,就有必要正式研究一下它们两者间的区别和联系了。

介绍

msdn上是这么描述属性的:

属性是一种成员,它提供灵活的机制来读取、写入或计算私有字段的值。 属性可用作公共数据成员,但它们实际上是称为访问器的特殊方法。 这使得可以轻松访问数据,还有助于提高方法的安全性和灵活性。

属性概述
属性是允许类公开获取和设置值的公共方法,它隐藏实现或验证代码。
get 属性访问器用于返回属性值,而 set 属性访问器用于分配新值。 这些访问器可以具有不同的访问级别。
value 关键字用于定义由 set 访问器分配的值。
属性可以是读-写属性(既有 get 访问器又有 set 访问器)、只读属性(有 get 访问器,但没有 set 访问器)或只写访问器(有 set 访问器,但没有 get 访问器)。

有一个实现属性的基本模式,该模式使用私有支持字段来设置和检索属性值。 get 访问器返回私有字段的值,set 访问器在向私有字段赋值之前可能会执行一些数据验证。 这两个访问器还可以在存储或返回数据之前对其执行某些转换或计算。

例:有一个名为 Student 的类,带有 age、name 和 code 的私有字段(即我们以前所说的属性,访问权限设定为私有,以后叫做字段)。我们不能在类的范围以外直接访问这些域,但是我们可以拥有访问这些私有域的属性。

class Student
    {
        private string code = "N.A";
        private string name = "not known";
        private int age = 0;

        // 声明类型为 string 的 Code 属性
        public string Code
        {
            get
            {
                return code;
            }
            set
            {
                code = value;
            }
        }
        // 声明类型为 int 的 Age 属性
        public int Age
        {
            get
            {
                return age;
            }
            set
            {
                if (value > 200)
                {
                    age = 200;
                }
                else
                {
                    age = value;
                }
            }
        }
        public override string ToString()
        {
            return "Code = " + Code + ", Name = " + Name + ", Age = " + Age;
        }
        // 声明类型为 string 的 Name 属性
        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
            }
        }
    }
        class Program
    {
        static void Main(string[] args)
        {
            // 创建一个新的 Student 对象
            Student s = new Student();

            // 设置 student 的 code、name 和 age
            s.Code = "001";
            s.Name = "Zara";
            s.Age = 210;
            Console.WriteLine("Student Info: {0}", s);
            // 增加年龄
            s.Age -= 100;
            Console.WriteLine("Student Info: {0}", s);
            Console.ReadKey();
        }
    }

执行结果:

例2:

在此示例中,TimePeriod 类表示时间间隔。 在内部,该类将时间间隔以秒为单位存储在名为 _seconds 的私有字段中。 名为 Hours 的读-写属性允许客户以小时为单位指定时间间隔。 get 和 set 访问器都会执行小时与秒之间的必要转换。 此外,set 访问器还会验证数据,如果小时数无效,则引发 ArgumentOutOfRangeException。

class TimePeriod
{
   private double _seconds;

   public double Hours
   {
       get { return _seconds / 3600; }
       set { 
          if (value < 0 || value > 24)
             throw new ArgumentOutOfRangeException(
                   $"{nameof(value)} must be between 0 and 24.");

          _seconds = value * 3600; 
       }
   }
}

class Program
{
   static void Main()
   {
       TimePeriod t = new TimePeriod();
       // The property assignment causes the 'set' accessor to be called.
       t.Hours = 24;

       // Retrieving the property causes the 'get' accessor to be called.
       Console.WriteLine($"Time in hours: {t.Hours}");
   }
}

自动实现的属性
在某些情况下,属性 get 和 set 访问器仅向支持字段赋值或仅从其中检索值,而不包括任何附加逻辑。
自动实现的属性通过以下方式定义:使用 get 和 set 关键字,但不提供任何实现。

例:

public class SaleItem
{
   public string Name 
   { get; set; }

   public decimal Price
   { get; set; }
}

class Program
{
   static void Main(string[] args)
   {
      var item = new SaleItem{ Name = "Shoes", Price = 19.95m };
      Console.WriteLine($"{item.Name}: sells for {item.Price:C2}");
   }
}
原文地址:https://www.cnblogs.com/wanjinliu/p/11657284.html