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进行属性的赋值,会提示未找到属性设置的方法。
那么查找一下原因吧。百度会告诉我们,这是因为属性没有set访问器原因。为什么会没有访问器呢?反编译看一下
前面我们提到了 ,属性的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)判断即可。