源地址:https://zhidao.baidu.com/question/1174413218458798139.html

我们知道,类成员包括变量和方法。如果希望其他类能够访问成员变量的值,就必须定义成公有的,而将变量设为公有public,那这个成员变量的就可以被任意访问(包括修改,读取),这样不利于数据安全。那怎么办呢?C#通过属性特性读取和写入字段(成员变量),而不直接直接读取和写入,以此来提供对类中字段的保护。属性可用于类内部封装字段。属性是C#面向对象技术中封装性的体现。注意:字段就是类的成员变量,为配合属性而这样称呼的。属性和字段的区别:属性是逻辑字段;属性是字段的扩展,源于字段;属性并不占用实际的内存,字段占内存位置及空间。属性可以被其它类访问,而大部分字段不能直接访问。属性可以对接收的数据范围作限定,而字段不能。(也就是增加了数据的安全性)最直接的说:属性是被“外部使用”,字段是被“内部使用”。要属性这种华而不实的东西做什么?为什么不直接放一个public字段?如:class Card
{ public string Name;
} 而非要做一个private字段+public属性?class Card{private string name;
public string Name{get { return this.name;}
public string sex;}//声明一个类去使用User类 class Property{static void Main(){//实例化一个张三User对象 User zs = new User();
//对其赋值 zs.name = "张三"; zs.sex = "男"; Console.WriteLine("姓名:" + zs.name + "性别:" +zs.sex); }
}通过编译执行,这段代码正常运行,这个程序乍看一下感觉没有什么问题。但是仔细分析,就会发现:所有字段都是公有的,不利于字段的保护,只要实例化了这个类,都可以修改其中的值。如果性别输入了男女之外的字符,系统是不会识别的。比如把zs.sex = "男";改成zs.sex = "牛";。运行代码结果肯定张三的性别成牛了...这个时候就不合逻辑了。现在大家可以明显的感觉到User类的封装非常不合理,存在着非常大的缺陷,那么该如何修改呢?这个时候大家马上会想到是不是可以专门声明一个方法给性别赋值呢,好!我们就来实现这个方法。using System; class User{public string name;
public string sex;
//SetSex方法 public void SetSex(string values){if (values == "男" || values =="女") {
sex =values;}else{Console.WriteLine("性别只能为“男”或“女”"); }}}class Property{static void Main(){User zs = new User();
zs.name = "张三"; //直接调用SetSex赋值 zs.SetSex("牛"); Console.WriteLine("姓名:" + zs.name + "性别:" +zs.sex); }
}SetSex这个方法乍一看还可以,但是不要忘记name和sex字段还是public属性,我们依然可以直接去调用它,或者说去修改它,一样可以把sex设为“牛”。给类的字段设置为public意味着破坏了类的封装,这样呢会存在潜在的危险。所以呢要设为private,这个时候就分别声明方法去读取和设置这2个字段,修改如下:using System; class User{//设为私有的 private string name;
private string sex;
//设置 public void SetName(string values){name = values;}//读取 public string GetName(){return name;}public void SetSex(string values){if (values == "男" || values =="女") {
sex =values;}else{Console.WriteLine("性别只能为“男”或“女”"); }}public string GetSex(){return sex;}}class Property{static void Main(){User zs = new User();
zs.SetName("张三"); zs.SetSex("牛"); Console.WriteLine("姓名:" + zs.GetName() +"性别:" +zs.GetSex()); }
}大家执行编译下看下效果是没有问题的。现在这个类的设计就比较合理了,我们看name和sex它们是private字段,也就是说在类的外部是不能访问的,这样呢就保证了它的安全性。当用户想给性别字段添加非法字段的时候,SetSex方法内会对这个添加的值进行判断,如果不为男或女,值就不会被添加。通过方法虽然解决了上面的问题,但是每创建一个对象,输入字段值时就必须调用上面方法。如果不知道,就无法调用。关键是不够简便。为了提高数据安全性,并且有效解决上面的问题,C#推出了属性。可以创建属性,将字段和属性封装在一起。通过属性可以像访问字段一样访问数据成员,实现数据的封装,避免使用非法数据赋值,保证数据完整性,同时类内部发生修改时,避免整个程序的修改。C#属性的应用1、打个比方我们有个网站,每当有新用户注册的时候,我们需要记录这些用户的信息。创建一个User类来记录用户的注册信息,包括用成员变量(字段)用户名,密码,性别。2、用属性封装3个字段,实现赋值规则用户名只能以字母开头,密码长度不小于6(默认6个1),性别只能是“男”或“女”。代码如下:User类:usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;namespaceWebsite{ classUser { stringname; stringpassword; string sex; publicstring Name { get{ return name; } set { if(char.IsLetter(value,0)) { name = value; } else { Console.WriteLine("用户名非法,必须以字母开头"); Console.WriteLine("用户名默认为:abc"); name = "abc"; } } } publicstring Password { get{ return password; } set { if(value.Length >= 6) { password = value; } else { Console.WriteLine("密码非法,密码长度不小于6"); Console.WriteLine("密码默认为:111111"); password = "111111"; } } } publicstring Sex { get{ return sex; } set { if (value.Equals("男") || value.Equals("女")) { sex = value; } else { Console.WriteLine("性别非法,必须为“男”或“女”"); Console.WriteLine("性别默认为:男"); sex = "男"; } } } publicvoid DisplayInfo() { Console.WriteLine("用户名:{0}", this.Name); Console.WriteLine("密码:0}", this.Password); Console.WriteLine("性别:{0}", this.Sex); } }}主类:usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;namespaceWebsite{ classProgram { staticvoid Main(string[] args) { Useru = newUser(); Console.WriteLine("===============用户注册==============="); Console.Write("请输入用户名:"); u.Name = Console.ReadLine(); Console.Write("请输入密码:"); u.Password = Console.ReadLine(); Console.Write("请输入性别"); u.Sex = Console.ReadLine(); Console.WriteLine("===============用户信息==============="); u.DisplayInfo(); } }}

【谁知道C#字段为什么用属性封装?】的更多相关文章

  1. 面向对象银角大王补充2-self就是调用当前方法的对象-静态字段,公有属性-封装的理解-继承的理解,普通方法,静态方法

    self是什么,就是一个函数,就是一个形式参数 4.self就是调用当前方法的对象 静态字段,公有属性 静态字段使用场景,每个对象中保存相同的东西时,可以使用静态字段,公有属性 5.封装的理解 类中封 ...

  2. C# 类属性封装、字段的详解

    今日敲代码时,突然感觉对类的属性封装.字段有点犯迷糊了..连基础的都不知道了,那敲的代码怎么能严谨高效的.果断拿起各种高级编程.大全啥的翻起来~~这不再把自己的理解写下来(定义都是直接抄书的),献给同 ...

  3. C#属性封装

    1.属性封装是为了保护与之相对应的字段的,保证字段的读取和赋值是否符合要求 2.属性可以分为:读写,只读,只写 3.允许外部访问的变量一定要申明为属性 4.属性的本质就是两个方法. 5.自动属性 6. ...

  4. K3精益版给物料添加属性,并在BOM中新增字段引用该属性

    1.给物料新增属性 打开“系统--基础资料--公共资料--核算项目管理”,然后双击物料,弹出核算项目类别-修改对话框.再点新增按钮: 输入你想新增字段的类型,长度,想要放置的位置. 相关属性里面选的是 ...

  5. Struts2框架的数据封装一之属性封装(属性封装的第二种方式:封装成javaBean)

    Struts2中提供了两类数据封装的方式? 第一种方式:属性驱动(有两种方式:一个对属性,另外一个是将参数封装到javaBean中) B. 在页面上,使用OGNL表达式进行数据封装.(将参数封装到ja ...

  6. java 属性封装

    //封装性 //封装概念: //1.是面向对象思想的三大特征之一 //2.封装细节是隐藏的,仅对外提供访问接口 //3.封装分类: //属性封装 //方法封装 //类的封装 //组件的封装 //模块化 ...

  7. python进阶01 面向对象、类、实例、属性封装、实例方法

    python进阶01 面向对象.类.实例.属性封装.实例方法 一.面向对象 1.什么是对象 #一切皆对象,可以简单地将“对象”理解为“某个东西” #“对象”之所以称之为对象,是因为它具有属于它自己的“ ...

  8. 在oracle中操作表及字段注释,查询一个表的所有字段名以及属性和约束

    1.查询表注释 SELECT * FROM USER_TAB_COMMENTS; 三列:TABLE_NAME,TABLE_TYPE,COMMENTS 2.查询字段注释 SELECT * FROM US ...

  9. hibernate字段名和属性

    字段名和属性名相同 Annotation:默认为@Basic 注意:如果在成员属性没有加入任何注解,则默认在前面加入了@Basic Xml中不用写column 字段名和属性名不同 Annotation ...

随机推荐

  1. IDA Pro权威指南学习笔记(一)

    一直不懂逆向,最近刚好不忙,于是学习逆向,用来做笔记,顺便和大家分享交流. 参考书籍<IAD PRO权威指南> 工具: PETools: ETools 是另一款很好的PE文件编辑工具,以前 ...

  2. App启动原理和启动过程

        一.程序启动原理 1.1.main函数中执行了一个UIApplicationMain这个函数UIApplicationMain(int argc, char *argv[], NSString ...

  3. BigDecimal的equals与compareTo

    equals方法的话会不仅会比较值的大小,还会比较两个对象的精确度, compareTo方法则不会比较精确度,只比较数值的大小

  4. 关于android中出现failed to read row 0,column -1错误

    该错误出现的原因是Cursor.getColumnIndex()的参数列名不存在或者错误,这时返回值为-1.出现该错误

  5. matlab基础功能实践

    一.matlab在高等数学中的应用(<数学建模算法与应用>P453) 1.求极限 syms x b=limit((sqrt(1+x^2)-1)/(1-cos(x))) syms x a b ...

  6. a标签中href=""的几种用法(转)

    a标签中href=""的几种用法   标签: html / a标签 / javascript 46371 众所周知,a标签的最重要功能是实现超链接和锚点.而且,大多数人认为a标签最 ...

  7. ngx-bootstrap使用04 carousel组件

    1 carousel 是一个通过循环播放图片.文本的幻灯片:就像一个旋转旋转木马一样,但是不支持嵌套使用 2 如何使用 2.1 搭建ngx-bootstrap使用环境 参见博文:点击前往 2.2 在模 ...

  8. EZOJ #79

    传送门 分析 在经过若干次操作之后一定会产生一堆环 而我们又发现从一个点到另一个点实际可以经过所有环 于是问题就转换成了$k_1s_1 + k_2s_2 + ... + len = t$ 其中$s_i ...

  9. c语言中会遇到的面试题

    预处理器(Preprocessor) 1 . 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)         #define SECONDS_PER_YEAR (60 ...

  10. Qemu虚拟机 玩树莓派最新版系统 (截止2017-04-10)

    Qemu虚拟机可以玩 树莓派,大家都知道了吧.可是网上的教程好老,都是2012年的.我按照教程下载了最新版版本的树莓派系统怎么也跑不起来. 研究了好久,终于找到一个简单的方法,特意分享出来.转载请注意 ...