记录点滴收获,汇聚知识乐园

脚步无法到达的地方,目光可以到达;目光无法到达的地方,梦想可以到达

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

属性详解

 

属性使用起来像字段,本质上是方法,属性是类成员重要的组成部分,访问属性和访问公共数据成员一样方便,但是属性的访问机制和公共数据成员的访问机制完全不同,它实际上是调用了内部相应的方法,那我们为什么不直接使用公共数据成员,而要使用属性了,首先我想说一下属性和字段的区别,C#是面向组件的编程,而字段是一个组件的实现细节,实现细节应该隐藏起来,,是不能暴露在组件外部的,应该定义为私有的,而属性是组件提供给外部的访问接口,必须公开。

首先我想定义一个学生类,为了紧扣主题,该学生类暂时只包含学生的基本信息:年龄、姓名、学生人数(静态只读)。不用充分考虑,我们肯定会写出这样的一段代码:

class Student

{

   public int _age;

   public string _name;

   public static readonly _count;

}

下面我们来分析一下它的缺点:在这个类中,我们定义了三个公有数据成员,外部在访问这三个数据成员时可以随便的修改它们的值,严重违背了C#的封装机制,所以这样定义并不合理,所以我们需要使用属性来实现对数据的封装。为了防止外部能访问到这三个数据成员,将其私有化。

class Student

    {

        private int _age;  //私有字段

        private string _name; //私有字段

        private static int _count;  //私有字段

        public int Age   //属性Age

        {

            get { return _age; }

            set 

            {

                if (value < 0 || value > 100)

                {

                    throw new ArgumentOutOfRangeException("the value must be in 0 between 100");

                }

                else

                {

                    _age = value;

                }

            }

        }

        public string Name  //属性Name 

        {

            get { return _name; }

            set { _name = value; }

        }

        public static int Count   //只读静态属性

        { 

            get { return _count; } 

        }            

    }

几点说明:

  • 属性要定义名称和类型,且类型不能是void。
  • 属性是不能重载的。我们不能定义名称相同、类型不同的两个属性。
  • 属性一般需要定义getset方法来操作类内部的私有支持字段,如上面的_name, _age等。Set方法中包含隐藏参数叫做value,表示赋给属性的值。
  • 只读只写属性:可以通过省略set来定义只读属性(如Count属性),或者省略get来定义只写属性。
  • CLR支持静态、实例、抽象和虚属性。例子中的Name和Age就是我们最常用的实例属性,Count就是静态只读属性的例子
  • 使用属性时会产生相应的智能感知,就像使用公用字段一样

 自动实现的属性——AIP

 

 public int Age{set;get;}

 

注意一下几点:

 

① AIP的get和set方法中不能添加断点调试。

② AIP属性必须是同时可读可写的。如果只定义get或者只定义set,则必须两个都显式实现,不能使用AIP。

③ 想要序列化或者反序列化的类中,不要定义AIP。因为运行时序列化引擎将字段名持久化到了序列化流中,而且每次编译时这个名字还有可能改变。

 

索引器:通过给访问器添加参数,一个索引器可以访问更多的属性

class IndexerExample<T>

    {      

       private T[] array = new T[2];

        public T this[int i]

        {

            get { return array[i]; }

            set { array[i] = value; }

        }

    }

class Application

    {

        static void Main()

        {

            IndexerExample<string> indexer = new IndexerExample<string>();

            indexer[0] = "guowenhui";

            indexer[1] = "dongyaguang";

        }

    }

这里我想再谈一个问题,可能与本篇的主题不太相关,就当是本篇的延伸,

  大多数的ASP.NET服务器控件存储其属性值的方式都是通过ViewState来存储的,而不是通过类的私有化字段进行存储的,这里我想解释一下为什么。

    首先我们需要知道ViewState是什么,ViewState是一个定义在System.Web.UI.Control类中的一个Protected型的属性,同时所有的服务器控件及用户自定义控件都是继承自System.Web.UI.Control,因此这些控件均具有ViewState属性。ViewState的项是可以存储任何类型的值的(实际上任何赋值给ViewState的变量都会被装箱为Object类型的变量),很多人可能会这么想,当我们给一个TextBox控件的Text属性赋值的时候,应该是这样进行存储的

Public String Text

{

     get { return _text; }

     set { _text=value; }

}

这里_text为类中定义的私有字段成员,但是我们注意,大部分的ASP.NET服务器控件在存储属性值的时候并不是通过这种方式实现的,而是通过ViewState,通过Reflector查看TextBox.Text属性的源代码你可以看到类似如下的代码:

Public String Text

{

     get { return (String)ViewState["Text"]; }

     set { ViewState["Text"]=value; }

}

所以在设计自定义组件的时候,最好遵循这种方式,这里还有一个问题,在以ViewState位存储方式的时候,如果实现属性的默认值,我们因该怎么做了,很多人可能会觉得是这样实现的

 class TextControl

    {

        private String _text = "DefaultValue";

        public String Text

        {

            get { return _text; }

            set { _text = value; }

        }

    }

这里我想用控件的ViewState属性来设定默认值,我们应该怎么做了。

class TextControl

    {      

        public String Text

        {

            get { return ViewState["Text"]==null?"DefaultValue":(String)ViewState["Text"]; }

            set { ViewState["Text"] = value; }

        }

    }

 

posted on   guowenhui  阅读(478)  评论(0编辑  收藏  举报

编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示