源地址: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. 【转】 Pro Android学习笔记(八六):了解Package(5):使用lib

    目录(?)[-] 在项目中使用lib 源代码 了解一些机制 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowin ...

  2. iOS下拉图片放大

    效果图 开始简单的代码过程 其实思路很简单 就是 让tableView偏移 一图片的高度,然后在把图片添加到tableView中,然后再监听didScrollView,在里面改变图片的frame - ...

  3. Celery-4.1 用户指南: Calling Tasks(调用任务)

    基础 本文档描述 Celery 中任务实例和 Canvas 使用的统一 “Calling API”. API 中定义了一个执行选项的标准集,以及三个方法: - apply_async(args[, k ...

  4. “百度杯”CTF比赛 十一月场(Misc)

    签到题: 题目提示: 文件在i春秋的ctf2群里,加群下载文件 下载下来之后发现有压缩密码 题目提示有提示解压密码:key:ichunqiumemeda 打开文件,得到flag 签到题2: 点击下载附 ...

  5. Eclipse中classpath和deploy assembly的文件位置

    classpath的配置信息存储在工程根目录下的.classpath文件 deploy assembly配置信息存储在工程目录下的.settings\org.eclipse.wst.common.co ...

  6. Samba服务学习报错总结

    1 2 3 4 5 此文献来至百度文库 http://wenku.baidu.com/link?url=hkHembjXcjoYRU9ky34a46Lzv5SAEutwa0v1_F8INQsdg_KK ...

  7. AOP基础-JDK动态代理

    动态代理技术就是用来产生一个目标对象的代理对象的,代理对象应与目标对象(被代理的对象)有相同的方法,实现对目标对象访问的拦截,并增强目标对象的一些功能,而不需要目标对象去做任何的更改,使得目标对象有更 ...

  8. executeUpdate,executeQuery,executeBatch 的区别

    executeQuery : 用于实现单个结果集,例如: Select 一般使用executeQuery 就是来实现单个结果集的工具 executeUpdate 用于执行 INSERT.UPDATE ...

  9. ActiveMQ (一) 介绍与安装

    ActiveMQ是消息中间件的一种 ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线.ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provide ...

  10. requestLayout, invalidate和postInvalidate的异同

    requestLayout 当一个VIEW的布局属性发生了变化的时候,可以调用该方法,让父VIEW调用onmeasure 和onlayout重新定位该view的位置,需要在UI线程调用 invalid ...