本文描述内容转载 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. Grafana安装配置介绍

    一.Grafana介绍 Grafana是一个可视化面板(Dashboard),有着非常漂亮的图表和布局展示,功能齐全的度量仪表盘和图形编辑器,支持Graphite.zabbix.InfluxDB.Pr ...

  2. Nginx+Tomcat集群配置

    Nginx+Tomcat集群配置 一台虚拟机作为Nginx服务 两太虚拟机配置Tomcat+jdk环境 Nginx测试 启动: cd usr/local/nginx/sbin ./nginx ---& ...

  3. Python序列化-pickle和json模块

    Python的“file-like object“就是一种鸭子类型.对真正的文件对象,它有一个read()方法,返回其内容.但是,许多对象,只要有read()方法,都被视为“file-like obj ...

  4. [LightOJ 1287] Where to Run

    Where to Run Last night you robbed a bank but couldn't escape and when you just got outside today, t ...

  5. Liunx 更新环境时用到的命令

    1.进入项目文件所在位置:cd/home/zhaorg/shelly62/apache-tomcat-7.0.5.2/bin 2.关闭服务:./shuntdown.sh或者 sh.shuntdown. ...

  6. RockerMQ消息消费、重试

    消息中间件—RocketMQ消息消费(一) 消息中间件—RocketMQ消息消费(二)(push模式实现) 消息中间件—RocketMQ消息消费(三)(消息消费重试) MQ中Pull和Push的两种消 ...

  7. web.xml之env-entry

    1.目的 定义一个jndi变量 2.schemas定义 2.web.xml中定义变量 <web-app> ... <env-entry> <env-entry-name& ...

  8. python文件管理

    文件没有修改操作,修改的方式为打开文件--读取文件--内存中编辑文件--将内容写入文件 打开文件方式 with open('a.txt','w') as f: #操作系统自动关闭文件 f.write( ...

  9. Win10系列:JavaScript 动画1

    在应用程序中使用动画会使应用显得更加生动,进而给用户带来良好的视觉效果.例如,当用户将某个项添加到列表时,新项不会立即出现在列表中,而是采用动画形式到达相应位置,并且列表中的其他项也采用动画形式移动到 ...

  10. 尚学堂java 参考答案 第八章

    一.选择题 1.BD 解析:B:Integer是对象,所以默认的应该是null对象.D使用的是自动装箱 2.A 解析:String类的对象是final型,是不能修改的,concat()方法是生成一个新 ...