c#-关于自动属性的思考

时间:2022-03-13 14:55:46

自动属性是什么

自动属性就是写的时候只写一个属性,并不写字段,一般情况下也不实现。

为什么要用自动属性

下面的程序一测试了一下在一般的类中使用自动属性的情况;发现编译器会在生成解决方案的时候会自动生成一个私有的字段,这个可以在一些反编译软件里都可以看到。在类中使用自动属性的目的就在于可以不用写字段了,但是问题又出现了,既然你自动属性里面没有什么实现,为什么不直接用一个public的字段呢,连set,get和一对花括号两个分号都省了呢?想了想大概是编程习惯的原因,人们习惯调用大写的属性,而不是小写的字段,用属性来保护字段,那么为什么不把字段大写呢,同样也是编程习惯问题,推荐字段写成小写,前面还有个下划线,编程习惯统一起来容易理解项目。

如果把自动字段实现一下会怎么样

用问题来驱动我们学习比较好,实现一下怎么样,会不会爆炸?我试了一下把程序一的自动属性Age实现了一下,发现必须同时实现get方法和set方法,如果只实现其中一个就会编译不通过,我猜实现set和get方法之后这个属性就不是一个属性了,只能是一个代码段,代码段里面有两个方法,因为实现之后反编译就没有自动生成字段。如果只实现一个另一个没有实现就会提示类不是抽象类什么的,不是抽象类就不能不实现方法,而又没有生成字段。说明这时候编译器认为这只是一个代码块了。

那么我们该怎么用自动属性呢。

有两个使用场景

1.在接口中定义,继承接口的类就可以用了。
2.当你有个字段不需要限制访问,你为了编程习惯又不想写成公有字段,同时你有懒得主动写那个字段名的时候,就使用自动属性吧。

接口怎么用自动属性

在上面的使用场景中接口中是可以声明自动属性的,声明之后意味着继承接口的所有非抽象的子类都必须实现这个自动属性,抽象的子类就不用实现了。那么又不知道生成的字段叫什么名字,怎么实现呢,答案是并没有办法具体实现,只能按照接口的写法照抄一遍,这样看来接口中用自动属性并没有什么卵用。唯一的用户就是强制非抽象子类必须有这个属性,何必呢。在程序二里发现如果不实现,编译时不通过的。得出的结论是接口中还是不要用自动属性。那么自动属性的唯一作用就是在符合编程规范的同时懒一把。

其它语法

接口的方法不允许添加访问修饰符,默认就是public(类默认是private),不能实现(区别于抽象类),子类实现时不用override(不同于抽象类),不能写字段;可以写自动属性(并没有什么卵用,也可能是我知识太浅薄)

程序一

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _31_interface
{
    class Program
    {
        static void Main(string[] args)
        {
            Person p = new Person();
            p.Name = "leifeng";
            p.Age = 10;
            Console.WriteLine("name is {0},age is {1}",p.Name,p.Age);
            Console.ReadKey();
        }
    }
    public class Person
    {
        public string Name
        {
            set;
            get;// { return "SB"; }
        }
        //Cannot write in this way,because this will cause dead ciculation;in Set and Get,we can not use auto properity;
        //so we would better not to fulfill the set and get method of properity;
        //so if we need not to limit the get and set method,we can use the auto properity, but why not use the public field;
        //So the conclusion is we can only use the auto properity in Interface;
        //what interests me is that we can not just fulfill one of the tow method;
        public int Age
        {
            set;
            get; { return 20; }
        }
        private char _gender;
        public char Gender
        {
            get { return _gender; }
            set { _gender = value; }
        }
    }
}

程序二:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _31_interface
{
    public interface IRunable
    {
         int NumOfLegs
        {
            set;
            get;
        }
         void Fly();
    }
    public class Car:IRunable
    {
        public int NumOfLegs
        {
            get;
            set;
        }
        public void Fly()
        {
            Console.WriteLine("Car can run on the road!");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {

            Console.ReadKey();
        }
    }

}