本文描述内容转载 https://zhidao.baidu.com/question/1174413218458798139.html 感谢 冥冥有你PD 的解答!!!

问题思索1

类成员包括变量和方法。如果希望其他类能够访问成员变量的值,就必须定义成公有的,而将变量设为公有public,那这个成员变量的就可以被任意访问(包括修改,读取),这样不利于数据安全。那怎么办呢?

解决方案

1.C#通过属性特性读取和写入字段(成员变量),而不直接直接读取和写入,以此来提供对类中字段的保护。

2.属性可用于类内部封装字段。属性是C#面向对象技术中封装性的体现(注意:字段就是类的成员变量,为配合属性而这样称呼的)

属性和字段的区别

1.属性是逻辑字段;

2.属性是字段的扩展,源于字段;

3.属性并不占用实际的内存,字段占内存位置及空间。

4.属性可以被其它类访问,而类中大部分字段不能直接访问。

5.属性可以对接收的数据范围作限定,而字段不能(也就是增加了数据的安全性)最直接的说:属性是被“外部使用”,字段是被“内部使用”。

问题思索2

要属性这种华而不实的东西做什么?为什么不直接放一个public字段?

class Card
{

  public string Name;    //而非要做一个private字段+public属性?
}

#region ClassStart***************************************************

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);

  }
}

#Endregion ClassEnd***************************************************

通过编译执行,这段代码正常运行,这个程序乍看一下感觉没有什么问题。但是仔细分析,就会发现:所有字段都是公有的,不利于字段的保护,只要实例化了这个类,都可以修改其中的值。

如果性别输入了男女之外的字符,系统是不会识别的。比如把zs.sex = "男";改成zs.sex = "牛";

运行代码结果肯定张三的性别成牛了...这个时候就不合逻辑了。现在大家可以明显的感觉到User类的封装非常不合理,存在着非常大的缺陷,那么该如何修改呢?这个时候大家马上会想到是不是可以专门声明一个方法给性别赋值呢,

#region ClassStart***************************************************

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);

  }
}

#Endregion ClassEnd***************************************************

SetSex这个方法乍一看还可以,但是不要忘记name和sex字段还是public属性,我们依然可以直接去调用它,或者说去修改它,一样可以把sex设为“牛”。

给类的字段设置为public意味着破坏了类的封装,这样会存在潜在的危险。所以要设为private,这个时候就分别声明方法去读取和设置这2个字段。

#region ClassStart***************************************************

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());

  }
}

#Endregion ClassEnd***************************************************

现在这个类的设计就比较合理了,我们看name和sex它们是private字段,也就是说在类的外部是不能访问的,这样呢就保证了它的安全性。

当用户想给性别字段添加非法字段的时候,SetSex方法内会对这个添加的值进行判断,如果不为男或女,值就不会被添加。

通过方法虽然解决了上面的问题,但是每创建一个对象,输入字段值时就必须调用上面方法。

如果不知道,就无法调用。关键是不够简便。为了提高数据安全性,并且有效解决上面的问题。

C#推出了属性。可以创建属性,将字段和属性封装在一起。通过属性可以像访问字段一样访问数据成员。

实现数据的封装,避免使用非法数据赋值,保证数据完整性,同时类内部发生修改时,避免整个程序的修改。

C#类中字段封装为属性的更多相关文章

  1. c#类中字段和方法中变量的声明问题

    字段和局部变量的作用域冲突 某些情况下可以区分名称相同,作用域相同的两个标识符.原因是C#在变量之间有一个基本的区分,它把在类级别声明的变量看作 字段,而把在方法中声明的变量看作局部变量. class ...

  2. MyBatis系列二 之 数据库列名于程序实体类中字段名称不一致

    MyBatis系列二  之   数据库列名于程序实体类中字段名称不一致 情景:当数据库中的列名与我们程序实体类中的字段名称不一致         使用ResultMap节点配置信息  在映射文件中  ...

  3. 在动态sql的使用where时,if标签判断中,如果实体类中的某一个属性是String类型,那么就可以这样来判断连接语句:

    在动态sql的使用where时,if标签判断中,如果实体类中的某一个属性是String类型,那么就可以这样来判断连接语句: 如果是String类型的字符串进行判空的时候: <if test=&q ...

  4. Json串的字段如果和类中字段不一致,如何映射、转换?

    Json串是我们现在经常会遇到的一种描述对象的字符串格式.在用Java语言开发的功能中,也经常需要做Json串与Java对象之间的转换. fastjson就是经常用来做Json串与Java对象之间的转 ...

  5. Android Studio查看类中所有方法和属性

    ctrl+f3效果: alt+7效果: 注意区别:虽然所有方法都有,但是顺序自己一看效果便知.一个是根据类中的顺序,另一个是根据a-z的开头字母顺序. 百度查了一下快捷键是ctrl+f12.但是自己试 ...

  6. C#类中字段,属性与方法

    person类 using System; using System.Collections.Generic; using System.Linq; using System.Text; using ...

  7. 第8.11节 Python类中记录实例变量属性的特殊变量__dict__

    一. 语法释义 调用方法:实例. __dict__属性 __dict__属性返回的是实例对象中当前已经定义的所有自定义实例变量的名和值,用字典存储,每个元素为一个"实例变量名:值" ...

  8. 关于entityframework 自动生成实体类中加验证的属性重新生成后属性被覆盖解决办法

    1.手动创建一个部分类 (你可以手动创建 partial class, 内容为空) [MetadataType(typeof(AppleMetadata))] public partial class ...

  9. MOOC(7)- case依赖、读取json配置文件进行多个接口请求-测试类中调用封装的mock(10)

    封装mock后,在单元测试中调用 # -*- coding: utf-8 -*- # @Time : 2020/2/11 8:35 # @File : test_class_10.py.py # @A ...

随机推荐

  1. visual studio利用 indent guides 格式化代码 添加竖线

    点击 Visual Studio 2013 工具—扩展和更新—联机 然后输入indent guides 自动搜索出来这个插件(如图).注:Visual Studio 2010需要自己在网上下载安装. ...

  2. Beta阶段——第4篇 Scrum 冲刺博客

    Beta阶段--第4篇 Scrum 冲刺博客 标签:软件工程 一.站立式会议照片 二.每个人的工作 (有work item 的ID) 昨日已完成的工作 人员 工作 林羽晴 昨日完成获取提醒语句的接口函 ...

  3. Create JSON by Jackson API(转)

      原文地址: Create JSON by Jackson API Jackson API is a multi-purpose Java library for processing JSON. ...

  4. Mac系统安装和配置tomcat步骤详解

    一:下载 打开Apache Tomcat官网,选择需要的版本下载: 二:存放到本地 文件夹重名民为ApacheTomcat,放到/Users/计算机名/Library/目录下 三:启动Tomcat 打 ...

  5. 牛客网第一场 A Monotonic Matrix

    链接:https://www.nowcoder.com/acm/contest/139/A来源:牛客网 Count the number of n x m matrices A satisfying ...

  6. MSSQL内存架构及管理

    1.  MSSQL内存架构 相比较Oracle,MSSQL的内存区域并没那么清晰,但和Oracle类似,MSSQL内存区域大体也可以分为三个部分:buffer pool,query/workspace ...

  7. Vue 使用 vuelidate 实现表单验证

    表单验证的应用场景十分广泛,因为网站对用户输入内容的限制是非常必要的. 在vue中,我们使用vuelidate方便地实现表单验证. 官方文档在这里https://monterail.github.io ...

  8. Bellman-Ford算法——为什么要循环n-1次?图有n个点,又不能有回路,所以最短路径最多n-1边。又因为每次循环,至少relax一边所以最多n-1次就行了!

    单源最短路径 给定一个图,和一个源顶点src,找到从src到其它所有所有顶点的最短路径,图中可能含有负权值的边. Dijksra的算法是一个贪婪算法,时间复杂度是O(VLogV)(使用最小堆).但是迪 ...

  9. ftp主动模式与被动模式交互过程分析

    1.相关介绍 1.1主动模式和被动模式 主动模式:服务端通过指定的数据传输端口(默认20),主动连接客户端提交的端口,向客户端发送数据. 被动模式:服务端采用客户端建议使用被动模式,开启数据传输端口的 ...

  10. 正则表达式test()和exec()、 search() 和 replace()用法实例

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...