现在的位置: 首页 > 综合 > 正文

天轰穿C# -vs2010 – 04面向对象的编程之属性【原创】

2012年08月10日 ⁄ 综合 ⁄ 共 3048字 ⁄ 字号 评论关闭

老田:这就需要用属性了。而属性的使用和字段有很大的相似之处。如下例:

    1. 创建Windows桌面应用程序;
    2. 添加类Product,代码如下:

    using System;

    using System.Text;

     

    namespace _4_5_ProductManagr

    {

        public class Product

        {

            ///<summary>

            ///商品名   这是VS能够认识的字段的注释方式

            ///</summary>

            private string _name;

            // 价格    这种注释方式VS无法认识,也就无法提供智能提示

            private decimal _price;

            // 颜色

            private string _color;

            ///<summary>

            ///商品名称,可读可写    这是VS能够认识的属性的注释方式

            ///</summary>

            public string Name

            {

                get { return _name; }   //可读

                set { _name = value; }  //可写

            }

            ///<summary>

            ///价格,只写,不允许读

            ///</summary>

            public decimal Price

            {

                set { _price = value; } //可写

            }

            ///<summary>

            ///颜色,只读不可写

            ///</summary>

            public string Color

            {

                get { return _color; }  //可读

            }

        }

    }

      1. Form1的界面上做图4-16,这里就不详细讲了,如果你前面的每个示例都清楚命名习惯的话,完全猜得出来
    •  

                                  4-16

        1. 双击“添加”按钮,在按钮中添加代码,使按钮事件代码如下:

                private void button1_Click(object sender, EventArgs e)

                {

                    Product pd = new Product(); //实例化 pd 对象

                    pd.Name = tb_name.Text;

                    pd.Price = decimal.Parse(tb_price.Text);

                    pd.Color = tb_Color.Text;       //这行代码出错,为什么?

         

                    //添加完成后,填充下面预览的模块

                    lbl_name.Text = pd.Name;

                    lbl_price.Text = pd.Price.ToString();   //这行代码出错,为什么?

                    lbl_color.Text = pd.Color;

                }

          1. 上面代码中因为读写权限导致有两行代码出错,请问如何修正?

          小天:多简单啊,在添加的时候先对所有属性进行写操作(set),接着在预览中有全部进行读操作(get)。但是在ProductPrice属性是只写不许读,所以下面预览这里会出错,而Color是只读不许写,所以赋值的时候就出错了。所以要把这个例题修正的话,只需要为PriceColor这两个属性完善读写权限即可。

          老田:是的,从上面例题,可以总结出,属性的第一个最大作用就是控制读写权限。这是访问修饰符办不到的。所以我们不会考虑将字段公开来做属性。

          属性还有一个重要的特性,代码如下:

                  // 商品名

                  private string _name;

                  ///<summary>

                  ///商品名称

                  ///</summary>

                  public string Name

                  {

                      get {   //在向用户返回值之前检测

                          if (_name == "")

                              return "商品暂无名字";

                          else

                              return _name;

                      }  

                      set {  //在向字段写入值之前检测

                          if (value == "")

                              _name = "想骗我?不行的啦!";

                          else

                              _name = value;

                      }

                  }

                 小天:这个示例也简单,就是在向类中的数据字段读写值的之前先检查。不过我有点没有看懂,就是这里面的value是哪里来的??

                 老田:get访问器不带参数,且必须返回属性声明的类型。也不应为set访问器指定任何显式参数,但编译器假定它带一个参数,其类型也与属性相同,并表示为value

                 最后一个重要提醒。访问对象的属性,在属性名后面不加括号,访问类中的方法就一定要加括号。例如

                      lbl_name.Text = pd.Name;                 //Name是属性

                      lbl_price.Text = pd.Price.ToString();   //ToString是方法

           

                 小天:我怎么知道谁是属性,谁是方法呢??

                 老田:看下图4-17你就明白了。
           

           

                                                    4-17

                 实现属性还有种办法,如果属性的setget访问器中没有任何逻辑,就可以使用自动实现的属性。这种属性会自动实现基础成员变量。上例的代码如下:

          public string Name {get; set;}

          小天:你的意思是,使用这种方式则可以不在显示的申明private string _name这个成员变量。编译器会自动创建它。

          老田:是的,但是使用自动实现的属性,就不能在属性设置中进行属性的有效性验证。所以在上面的例子中,不能检查_name是否为空。但必须同时设置读写两个访问器。尝试把该属性设置为只读属性,就会出错:

          public string Name {get; }

           

          但是,每个访问器的访问级别可以不同。因此,下面的代码是合法的:

          public string Name {get; private set;}

                 小天:通过属性访问字段,而不是直接访问字段。这些额外的函数调用是否会增加系统开销,导致性能下降?

          老田:不需要担心这种编程方式会在C#中带来性能损失。C#代码会编译为IL,然后在运行期间进行正常的JIT编译,获得内部可执行代码。JIT编译器可生成高度优化的代码,并在适当的时候内联代码(即用内联代码来替代函数调用)。如果某个方法或属性的执行代码仅是调用另一个方法,或返回一个字段,则该方法或属性肯定是内联的。但要注意,在何处内联代码的决定完全由CLR做出。

          本文章为天轰穿原创作品,转载请注明出处及作者。

          抱歉!评论已关闭.