本文描述内容转载 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. awr相关

    手工生成awr快照SQL> exec dbms_workload_repository.create_snapshot; PL/SQL procedure successfully comple ...

  2. PAT Rational Sum

    Rational Sum (20) 时间限制 1000 ms 内存限制 65536 KB 代码长度限制 100 KB 判断程序 Standard (来自 小小) 题目描述 Given N ration ...

  3. 十、 持久层框架(MyBatis)

    一.基于MyBatis动态SQL语句 1.if标签 实体类Product的字段比较多的时候,为了应付各个字段的查询,那么就需要写多条SQL语句,这样就变得难以维护. 此时,就可以使用MyBatis动态 ...

  4. nop 4.1 Widget 探究- 视图组件

    1. 系统默认自带了一个NivoSlider 的Wdget. 在Nop.Web项目首页的HomePageTop里 这个写法是 ASP.NET Core MVC 中的新特性 视图组件,与局部视图相似,但 ...

  5. 把旧系统迁移到.Net Core 2.0 日记(4) - 使用EF+Mysql

    因为Mac 不能装SqlServer, 所以把数据库迁移到MySql,然后EntityFramework要改成Pomelo.EntityFrameworkCore.MySql 数据库迁移时,nvarc ...

  6. flex入门----基础知识

    传统的页面布局   在flex出现之前,双列布局,三列布局,动态盒居中,绝对居中布局等常见的布局均是采用dispaly+float+定位来布局的,一般包括以下几种布局策略: normal flow(文 ...

  7. py requests.post2

    # -*- coding: utf-8 -*-import jsonimport requestsheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 6 ...

  8. pycuda安装 python<3.0

    cd pycudapython ./configure.py –cuda-root=/usr/local/cuda –cudadrv-lib-dir=/usr/lib –boost-inc-dir=/ ...

  9. MySQL 占用cpu 100%

    目前的线上数据库,分为主从两个库,从库用来做比较耗时的数据统计分析. 今天top了一下从库服务器,发现mysqld 在很长一段时间都占用105% cpu,一开始以为是从库在处理主库的binlog. 两 ...

  10. JVM运行时内存区域

    JVM运行java程序时会将内存划分为若干个不同的数据区域: (1)程序计数器: 1.占用内存空间不大. 2.程序计数器相当于JVM所执行的字节码(jvm指令)的“行号指示器”,通过程序计数器的“值” ...