本文描述内容转载 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. Docker Nginx 配置多个子域名

    参考:nginx server_name实用:配置多个子域名 在腾讯购置了域名服务,想直接配置二级域名映射到指定端口,发现腾讯不支持端口映射的方式. 想了一下,域名默认解析80端口,只能通过nginx ...

  2. 【转】Entity Framework教程(第二版)

    源起 很多年前刚毕业那阵写过一篇关于Entity Framework的文章,没发首页却得到100+的推荐.可能是当时Entity Framework刚刚发布介绍EF的文章比较少.一晃这么多年过去了,E ...

  3. nginx升级教程

    1.说明 CVE-2016-4450,可通过构造特定数据包,可引发nginx引用空指针,导致nginx出错从而造成拒绝服务攻击. 影响1.3.9到1.11.0的所有版本,进行修复的1.10.1和1.1 ...

  4. telnet强制中断登录

    在telnet登录的时候,有时我们只是想测试某个账号密码是否正确 但是telnet不像ssh一样密码试错之后可以使用Ctrl+c强制中断,使如果要输错三次五次才给退出中断交互那是十分浪费时间和心情的 ...

  5. WINDOWS中, 如何查看一个运行中的程序是64位还是32位的

    转自:https://blog.csdn.net/dayday3923/article/details/78597453?locationNum=7&fps=1 方法一: 任务管理器法任务管理 ...

  6. error: http://ppa.launchpad.net lucid Release: The following signatures couldn't be verified because

    ubuntu 命令行sudo apt-get update W: GPG error: http://ppa.launchpad.net lucid Release: The following si ...

  7. windbg 定位崩溃问题

    三板斧如下: 使用windbg打开dump文件,设置好对应进程的 pdb 文件(这个很关键.为了避免releas优化导致符号文件错乱,我发布的所有                      relea ...

  8. python 列表切片

    列表切片是python语言独有的特征,大大方便了我们的编码. 首先,在介绍切片之前,必须要知道一个知识,就是python列表的读写,下标可以使用负数. insert,get,set 操作均可传入负数下 ...

  9. shell 文件条件判断

    按照文件类型进行判断 '-b 文件' 判断该文件是否存在,并且是否为块设备文件(是块设备文件为真) '-c 文件' 判断该文件是否存在,并且是否为字符设备文件(是字符设备文件为真) '-d 文件' 判 ...

  10. vue常见开发问题整理

    1.(webpack)vue-cli构建的项目如何设置每个页面的title 在路由里每个都添加一个meta [{ path:'/login', meta: { title: '登录页面' }, com ...