当前位置:编程学习 > C#/ASP.NET >>

C#无参属性

 

大家来讨论下C#无参属性这个东西到底有没有存在的必要?

永远不要公开类型的字段,面向对象设计和编程的重要原则之一就是 数据封装。如果公开类型的字段,会很容易的写出不恰当使用字段的代码。这里可以把字段声明为private,然后声明访问器方法。

    class test

    {

      

       private  string Name;

       public void SetName(string value)

       {

           Name = value;

       }

       public string GetName()

       {

           return Name;

       }

     

    }

复制代码

实现只读或只写就是这么简单,不实现一个索引器方法就行了。还可以将Setname方法标记为protected,就可以只允许派生类修改了。聪明的你也发现上面这个做法的缺点了吧,首先得去实现额外的方法,所以会产生更多的代码,其次,如果调用的时候必须调用方法,不能直接引用一个字段名。还好C#给我们提供了一个称为属性(property)的机制,它缓解了第一个缺点造成的影响,也消除了第二个缺点。

   class test

    {

      

       private  string name;

       public string Name {

           get { return name; }

           set { if ("狗剩" == value) { Console.WriteLine("系统崩溃,抛出异常"); return; } name = value; }

       }

     

    }

复制代码

属性可以用任意的可访问修饰符来标记。不能定义名称相同的属性。

如果只是为了封装一个支持字段而创建属性,C#还提供一一种更简单的语法,称为自动实现的属性(Automatically Implemented Property,简称AIP)。like this

   class test

    {

       public int Age

       {

           get;

           set;

       }

    }

复制代码

如果声明一个属性而不提供get/set实现,C#会自动为你声明一个私有字段。原始代码是这样的:

public int Age

{

    [CompilerGenerated]

    get

    {

        int num;

        num = this.<Age>k__BackingField;

    Label_0009:

        return num;

    }

    [CompilerGenerated]

    set

    {

        this.<Age>k__BackingField = value;

        return;

    }

}

 

复制代码

和直接声明一个public 的Age字段相比,自动实现的属性的优势在哪?两者存在一处重要的区别:使用自动实现的属性(AIP)意味着已经创建一个属性,访问该属性的时候会调用get/set方法。如果有一天你决定自己实现这个AIP的get/set,而不接受编译器默认的实现,那么访问这个属性的任何代码都不必重新编译。如果是一个public的Age字段,如果你把它更改为属性,那么访问这个字段的所有代码就都需要重新编译了。

凡事都有好有坏,那么AIP有哪些不讨人喜欢的地方呢:

1.如果使用字段声明的语法,可以包含初始化的部分,如果使用AIP就不行了,必须在咩个构造器中显示的初始化每个AIP。

2.AIP支持的字段名是由编译器决定的,而且每次重新编译,这个字段名可能会发生更改,这样一来,只要含有一个AIP就不能对类型的实例进行反序列化了。在任何想要序列化或反序列化的类型中,都不要使用AIP功能。

3.不能在AIP的get/set添加断点,所以不好检测程序在什么时候获取或设置这个属性。咱手动实现的就可以设置断点,不信你试试。

AIP功能是作用于整个属性的:要么都用,要么都不用,这意味这,如果显式的实现get那么set也要显式实现,反之亦然。

 

属性看起来与字段相似,但本质上是方法。属性与字段的区别如下:

1.属性可以是只读或只写的(get/set访问器方法),字段却总是可读可写的。

2.属性方法可能抛出异常,字段访问不会抛出。

3.属性不能作为out或ref参数传递给方法,字段可以。

class Program

    {

       public int Age

       {

           get {return 3 ;}

           set{}

       }

       int age;

        static void Main()

        {

            var t = new { name="XiaoBai",age=22 };

            test tt = new test();

            //tt.Name = "狗剩";

            Program p = new Program();

            some(out p.age);

            some(out p.Age);//属性,索引器或动态成员不得作为out或ref参数传递

          Console.ReadKey();

        }

        static void some(out int age)

        {

            age = 10;

        }

    }

www.zzzyk.com

4.属性方法可能花费较长时间执行,字段的访问都是立即完成。

5.属性方法可能需要额外的内存,或者返回一个不正确的引用,指向不属于对象状态一部分的某个东西,这样一来,对返回对象的修改就作用不到原始对象身上了,相反查询字段返回的总是正确的引用,它指向的东西保证是原始对象状态的一部分。使用会返回一个拷贝的属性时,非常容易引起混淆。

如果仔细研究下属性和字段的差别,你会发现只有在极个别的情况下属性才真正有用。属性唯一的好处就是提供了简化的语法,和调用普通方法(非属性中的方法)相比,属性不仅不会提升代码的性能,还会妨碍对代码的理解。

属性访问器的可访问性:

我们有时希望为get访问器指定一种可访问性,为set访问器指定另一种访问器:

    class test

    {

        public int Age

        {

            get { return age; }

            protected set { if (value < 0) Console.WriteLine("年龄错误!"); else { age = value; } }

        }

        int age;

    }

复制代码

如上所述,Age属性本身声明为public,意味这get访问器方法是公共的,可由所有代码访问,但是,注意set访问器方法被声明为protected,只能从test的内部定义的代

补充:软件开发 , C# ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,