前提须知: 只有get方法叫只读属性,只有set方法叫只写属性,两个方法都存在叫可读可写属性
先看个例子:
// 出于安全性需要,进行封装字段,我们把字段访问修饰符设成private私有,但是私有字段我们都知道只能在自己类中调用,于是我们就
// 有了属性这个概念来进行对字段数值的赋值(set方法)和取值(get方法)
public class Person
{
/* 字段名我们一般用下划线开头 (在有些公司里也许会统一字段名开头小写的标准) */
public string Name
{get { return _name; } /*get方法是对字段进行 取值时调用*/
set { _name = value; } /*set方法是对字段进行 赋值时调用*/
}
// 也许这时候您会问:这两个是方法吗,一般的方法至少是void fun( ){ } 这种吧,你这连个返回值类型和括号都没有叫什么函数,请您慢慢往下看
// 下面截图我们会通过 reflector这个反编译工具去看一下get 和set 这两个方法的本质
privatte int _age;
public string Age
{
get { return _age; }
set { _age = value; }
}
private char _sex;
public string Sex;
{
get { return _sex; }
set { _sex = value; }
}
private string _hobby;
public string Hobby
{
get { return _hobby; }
set { _hobby = value; }
}
private string _phone;
public string Phone
{
get { return _hobby; }
set { _hobby = value; }
}
public void show( )
{
Console.WriteLine("我叫{0},今年{1}岁,是个{2}生,兴趣是{3},电话是{4}.",this.Name,this.Age,this.Sex,this.Hobby,this.Phone);
}
/****
* 构造一个Person函数,以便于实例化对象时进行传参.(结合下面)
****/
10行 public Person (string Name, int Age, char Sex, string Hobby, string Phone) /*先写个很全参数的构造函数,就方便20和30行的简写了*/
{
this.Name = Name;
this.Age = Age;
this.Sex = Sex;
this.Hobby = Hobby;
this.Phone = Phone;
}
/* 当我们只想传递部分信息时可以创建多个构造函数,例如:只输入 姓名,爱好, 号码时调用一个新的构造函数 */
20行 public Person(string Name, string Hobby, string Phone) : this(Name, 0, '男', Hobby, Phone)
{
}
/* 再举个例子吧------>只输入姓名,年龄,性别 */
30行 public Person(string Name, int Age, char Sex) : this( Name, Age, Sex, "hobby", "phone") /* 继承参数最齐全的构造方法后,对自己没有的参数进行任意赋值 */
{
}
/*****************************************
* 20行代码同等与下面代码,不过我们发现这样写会重复性写很多多余的代码,所以我们这里用this关键词写成20行的形式
* 这样可以有效的避免重复性操作,所以我建议不去下面这种形式 (我个人认为代码能多简洁就多简洁)
* public Person (string Name, string Hobby, string Phone )
* {
* this. Name = Name;
* this.Hobby = Hobby;
* this.Phone = Phone;
* }
*****************************************/
// 下面这个用于输出的方法我就不优化了
public void show()
{
Console.WriteLine("我叫{0},今年{1}岁,是个{2}生,兴趣是{3},电话是{4}.",this.Name,this.Age,this.Sex,this.Hobby,this.Phone); / *小黑*/
// Console.WriteLine("我叫{0},兴趣是{1},电话是{2}.", this.Name, this.Phone); /*小红*/
// Console.WriteLine("我叫{0},今年{1}岁,是个{2}生.",this.Name,this.Age,this.Sex ); /*小粉*/
}
class Program
{
static void Main(string[ ] args)
{
/*上面构造函数的好处在于,不需要使用 [对象名].方法名( ) 的形式进行赋值,类在创建一个对象时会先去调用类的构造函数*/
Person black = new Person("小黑",17,'男',"游戏","110"); // 调用第10行的构造函数
Person red = new Person("小红","绘画","120"); // 调用第20行的构造函数
Person pink = new Person("小粉",21,"女"); //调用第30行的构造函数
black.show( );
red.show( );
Console.ReadKey( );
}
}
看图说话 : 通过reflector这个微软员工写的反编译工具,我们可以知道 get; set; 这两个方法的实际执行代码,如上面的Name属性
我们写的是:
private string _name;
public string Name
{get { return _name; } /*get方法是对字段进行 取值时调用*/
set { _name = value; } /*set方法是对字段进行 赋值时调用*/
}
通过反编译我们可以知道它的本质代码是:
public string get_Name( )
{
return this._name; /*get方法返回的其实是字段*/
}
public void set_Name( string value ) /* 这里接收了对象实例化时调用构造函数的参数 */
{
this._name = value; /*然后把值赋给了字段*/
}
从以上对比,我们可以知道属性工作的流程。也许您会问知道这些有什么用呢。嘿嘿,我们知道属性和字段的关系之后,可以同过在属性上写点东西,达到对字段的约束作用。
例如:
1. 让用户输入年龄时,用户可能输入负值如-17岁或者超过三位数如400岁这些不符合实际的数值,这时候我们就可以通过属性在用户输入时,通过set方法对输入的值进行约束。
Code部分:
public int Age
{
get { return _age; }
set
{
if (value < 0 || value > 110) /*在对年龄属性进行赋时可以进行判断*/
{
value = 0;
}
_age = value;
}
2. 在让用户进行填写性别时,输入的字符有可能是'公',而我们的目的是想显示'男'&'女',这时候我们就可以通过属性在打印时,通过get方法对输入的值进行约束.
Code部分:
public char Sex
{
get
{
if ( _sex != '男' && _sex != '女' )
{
_sex = '男';
}
return _sex;
}
set { _sex = value; }
}
总结一下:
那么什么时候对get方法进行约束,又什么时候对set方法进行约束呢。答:对属性进行赋值时对set方法进行约束,比如上面代码实例化对象进行传参 .属性进行读取数值时,用get方法进行约束,比如上面用show()方法进行输出时。
这次就写到这儿吧,脖子有点疼了。以上都是我学习的时候总结,留备自己再看.如有误区还请您在评论区指出或者补齐,这里感谢那些看完这篇blog的人,好吧你们说吧.