前言
我们在开发C#程序的过程中,经常需要使用属性,本文就是对C#中的属性做一个详细的介绍。
1、属性的声明
1.1 属性的声明(C#3.0之前的版本)
private int _Age;//字段
public int Age//属性
{
get
{
return _Age;
}
set
{
_Age = value;
}
}
1.2 自动实现的属性(C#3.0之后的版本)
public int Age { get; set; }
2、属性的初始化
2.1 属性的初始化(C#3.0之前的版本)
Age =10;
2.2 属性的初始化(C#3.0之后的版本)
public int Age { get; set; } = 100;
3、属性的验证
当设置的值大于100时,改成设置100
private int _Age;
public int Age
{
get
{
return _Age;
}
set
{
if(value>100)//设置的值大于100时,取100
{
value = 100;
_Age = value;
}
}
}
下面的属性设置的值为空或者Null时直接抛出异常
private string _Name;
public string Name
{
get
{
return _Name ;
}
set
{
if(value==null)//设置的值大于100时,取100
{
throw new ArgumentNullException(nameof (value));
}
else
{
if(value=="")
{
throw new ArgumentException("last name cannot be blank",nameof(value));
}
_Name = value;
}
}
}
上述例子中nameof操作符的作用是:在抛出ArgumentException这种异常的时候会以字符串的形式显示出参数名的标识符
4、只读属性
1)
如果尝试为属性Name赋值,例如:Name = “小程”,则会报错,错误为“无法为属性赋值,因为它是只读的”
public string Name { get; } = "小王";
2)数组类型的属性比较特殊,因为我们声明了一个数组类型的属性,我们可以改变数组中元素的值,但是如果我们尝试改变数组的长度,那么会报错,错误为“无法为属性赋值,因为它是只读的”,所以系统认为对数组属性的赋值是改变数组的长度,所以利用这个特性我们可以保护数组的长度不会被改变,同时我们不影响我们给数组中的元素赋值(一般不怎么这样使用),如下:
public bool[] cell { get; } = new bool[2];
cell[0] = false;//ok
cell[1] = false;//ok
cell = new bool[3];//错误,无法为属性赋值
5、属性作为虚字段使用
public string FirstName { get; set; }
public string LastName { get; set; }
public string Name
{
get
{
return $"{FirstName } {LastName }";
}
set
{
string[] str = value.Split(new char[] { ' ' });
if(str.Length ==2)
{
FirstName = str[0];
LastName = str[1];
}
else
{
throw new ArgumentException (nameof (value));
}
}
}
以上代码可以看出Name属性并没有与之对应的可以存储数据的字段,只不过是存储到别的属性里面去了,此时FirstName 、LastName 就相当于Name属性的字段,这样的用法称为虚字段。
6、为取值方法和赋值方法指定访问修饰符
public string Name { get;private set; }
这里要注意几点,如下:
1)以上Name属性中对赋值方法添加了私有的访问修饰符,在申明该属性的类中可以对该属性进行赋值,但是在类外不能赋值,所以我们可以通过在构造函数中对Name属性进行赋值,对于类外的调用该属性,只能取值;
2)不要只提供只写属性,这样做好像没有什么意义;
3)不要让属性的赋值方法的访问比取值更轻松,例如将get方法声明为private的,将set方法申明为public就会有问题,get一定要比set访问权限要高一个级别,否则会报错。
7、属性不能作为ref或者out的参数使用
因为ref 和out参数使用时需要将内存地址传递给目标方法,但是属性可能是没有字段的虚字段或者是只读、只写的,所以无法传递地址,所以说属性不能作为ref或者out参数使用。