属性赋初始值的四种写法--C#6.0新特性

1 介绍

 在C# 6.0 语法出来前,属性的赋初始值使用get;set;虽然已经相对于最原始的写法简洁了非常多,但是还不够,还不够,还不够。。。今天刚好一直在想着前几天朋友问我的有关属性赋初始值的问题,便自己试了一下,感觉6.0提供了更好的写法。

2 代码

 (1)原始写法

     在不知道哪个版本的C# 中,提供了最原始的写法。那么上代码看一下

        private string _text = null;
        public string text
        {
            get
            {
                return _text;
            }
            set
            {
                _text = value;
            }
        }

    这应该是最原始的写法了,应该也算是最麻烦的一种写法。但是,接下来所说的所有写法,都算是语法糖,经过反编译之后,还是写成这种写法。

(2)6.0之前的写法

不得不提的是,巨硬真的是对开发者真的贴心,虽然经常会好心办坏事。那么看一下有了语法糖之后是怎么写的

    public string text
     {
         get;
         set;
     }

可以明显看出来,有了语法糖之后,真的是写起来非常舒服。那么就有一个问题:如果给属性赋初始值,在6.0语法出来以前,据我所知有两种

1 、构造函数

2、 不适用这个语法糖,用第一种写法

按照微软的贴心程度以及C#在语法糖的道路上越来越远,在6.0就提供了新的语法糖

(3)属性允许赋初始值

 手握这颗语法糖,那么就可以使用新的写法了,那么来看一下:

     public string text
        {
            get;
            set;
        } = "王二狗";

可以明显看出来,这种写法是比较简单的。不慌,还有一颗糖可以吃。

(4)在属性/方法里面使用Lambda表达式

 有了这颗糖,我们再来看一下怎么写:

 public string text => "二狗子";

 那么这句是不是更简洁了,在6.0中允许使用lambda表达式赋初始值,根据lambda的一系列规则之下,就是这个样子了。具体lambda的规则,在这里我就不再详细解释了。

3 例子

    上面只是最简单的用法,那么我们来举个栗子吧。

    找个场景吧:在类里 ,有一个属性Text,属性类型为string

     public  string Text
        {
            get;
            set;
        }

    现在需要根据string是不是为空来对另一个属性flag进行复制。那么我们看一下应该怎么写

  (1)   原始写法

        private bool _flag = true;
        public bool flag
        {
            get
            {
                if (Text == "")
                {
                    return true;
                }
                return false;
            }
            set
            {
                _flag = true;
            }
        }

使用最初的写法来写,以前也是一直都这么写的,确实是比较麻烦的,写了几次都记不住这个写法。

(2)新语法

public bool flag => Text == "" ? true : false;

  比较一下吧,想一想,两种写法比较一下 ,哪个好很显然了。

4 总结

    有些人数,C#的语法糖太多了,程序员都成了傻子了,但是实际用起来,还是会叫真香。

    那么,为什么我不用2中(3)属性允许赋初始值这种写法呢? 因为水平有限,不会写。 


开玩笑

       public bool flag
        {
            get;
            set;
        } = Text == "" ? true : false;

      这种写法中,Text不可引用非静态字段,这样的情况下,那么就需要将Text加上一个static,变为非静态字段。

好啦 就写到这里吧,如有不正确,请指正!


2018.11.07日更新

 针对使用ORM(主要是用反射)来对属性进行赋值时,会报错,进行补充说明。如果不是使用orm进行赋值,且在程序中不对该属性赋值,则不会报错。

(1)问题

先说下功能:实体类中有两个字段,是默认赋值的,原本使用lambda表达式进行赋初始值。

private string chkTypeBH => string.IsNullOrEmpty(parentChenkID) ? "01" : "02";

private string chkTypeMC => string.IsNullOrEmpty(parentChenkID) ? "主动检查" : "到期复查";

那么在查询数据的时候,如果使用ORM进行属性的赋值,会提示未找到属性设置的方法。

                  属性赋初始值的四种写法--C#6.0新特性_第1张图片

那么查找一下原因吧。百度会告诉我们,这是因为属性没有set访问器原因。为什么会没有访问器呢?反编译看一下

                                 属性赋初始值的四种写法--C#6.0新特性_第2张图片 

前面我们提到了 ,属性的get;set;但是这里只有get,也就是该属性为只读属性。所以:因为没有提供set,所以会报错。

那么应该怎么做呢?提供三种思路吧

(1)设置为private

将属性设置为private,在反射的时候,是只获取public类型的字段,自然也就不会报错啦

  (2)老老实实重写吧

 采用老方法进行get;set;吧

         private string chkTypeBH;
       
        public string ChkTypeBH
        {
            get
            {
                return string.IsNullOrEmpty(this.parentChenkID) ? "01" : "02";
            }
            set
            {
                chkTypeBH = value;
            }
        }
        private string chkTypeMC;
        
        public string ChkTypeMC
        {
            get
            {
                return string.IsNullOrEmpty(this.parentChenkID) ? "主动检查" : "到期复查";
            }
            set {
                chkTypeMC = value;
            }
        }

(3)在反射中进行修改

  在进行反射赋值时,加一句if(prop.canwrite)判断即可。

 

你可能感兴趣的:(C#语法)