C#类中字段封装为属性
本文描述内容转载 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#类中字段封装为属性的更多相关文章
- c#类中字段和方法中变量的声明问题
字段和局部变量的作用域冲突 某些情况下可以区分名称相同,作用域相同的两个标识符.原因是C#在变量之间有一个基本的区分,它把在类级别声明的变量看作 字段,而把在方法中声明的变量看作局部变量. class ...
- MyBatis系列二 之 数据库列名于程序实体类中字段名称不一致
MyBatis系列二 之 数据库列名于程序实体类中字段名称不一致 情景:当数据库中的列名与我们程序实体类中的字段名称不一致 使用ResultMap节点配置信息 在映射文件中 ...
- 在动态sql的使用where时,if标签判断中,如果实体类中的某一个属性是String类型,那么就可以这样来判断连接语句:
在动态sql的使用where时,if标签判断中,如果实体类中的某一个属性是String类型,那么就可以这样来判断连接语句: 如果是String类型的字符串进行判空的时候: <if test=&q ...
- Json串的字段如果和类中字段不一致,如何映射、转换?
Json串是我们现在经常会遇到的一种描述对象的字符串格式.在用Java语言开发的功能中,也经常需要做Json串与Java对象之间的转换. fastjson就是经常用来做Json串与Java对象之间的转 ...
- Android Studio查看类中所有方法和属性
ctrl+f3效果: alt+7效果: 注意区别:虽然所有方法都有,但是顺序自己一看效果便知.一个是根据类中的顺序,另一个是根据a-z的开头字母顺序. 百度查了一下快捷键是ctrl+f12.但是自己试 ...
- C#类中字段,属性与方法
person类 using System; using System.Collections.Generic; using System.Linq; using System.Text; using ...
- 第8.11节 Python类中记录实例变量属性的特殊变量__dict__
一. 语法释义 调用方法:实例. __dict__属性 __dict__属性返回的是实例对象中当前已经定义的所有自定义实例变量的名和值,用字典存储,每个元素为一个"实例变量名:值" ...
- 关于entityframework 自动生成实体类中加验证的属性重新生成后属性被覆盖解决办法
1.手动创建一个部分类 (你可以手动创建 partial class, 内容为空) [MetadataType(typeof(AppleMetadata))] public partial class ...
- MOOC(7)- case依赖、读取json配置文件进行多个接口请求-测试类中调用封装的mock(10)
封装mock后,在单元测试中调用 # -*- coding: utf-8 -*- # @Time : 2020/2/11 8:35 # @File : test_class_10.py.py # @A ...
随机推荐
- Echarts 简单报表系列三:饼状图
代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
- 【LeetCode】成对交换节点
e.g. 给定链表 1->2->3->4,返回 2->1->4->3 的头节点. 我写了个常见的从头节点遍历,少量的奇数个或偶数个数据都能成功重新排列.但链表过长时 ...
- ActiveMQ 配置jdbc主从
使用 jdbc 方式配置主从模式,持久化消息存放在数据库中. 在同一时刻,只有一个 master broker,master 接受客户端的连接,slave 不接受连接.当 master 因为关机而下线 ...
- 文献管理软件zotero的一点使用感受作者: 杨林畅
作者是我的本科同学叶家鑫 http://www.renren.com/profile.do?id=240875124 文章写于去年12月,我做了一些排版上的修改,括号内的蓝字为我所加 ---- zot ...
- Win10系列:UWP界面布局基础4
类型转换 前面讲到过,在定义元素时可以通过Attributes特性方式为其设置属性并为属性赋值,在实际开发中所赋予的值可能和属性本身的数据类型不相符,这时XAML解析器就会使用类型转换器(Type C ...
- Win10系列:VC++媒体播放
媒体播放包括视频播放和音频播放,在开发Windows应用商店应用的过程中可以使用MediaElement控件来播放视频文件和音频文件.本节将通过一个具体的示例介绍如何使用MediaElement控件来 ...
- java将字符串根据空格进行分割,使用split方法
public class D { public static void main(String[] args) { String b = "Hello Java World"; S ...
- Unity中物体碰撞后去掉相互之间的反弹力
最近自制了一个的角色控制器(没有重力的角色)时发现,角色碰撞到墙壁之后会有一个小小的反弹力导致角色有一个微弱的反弹位移,这样给人一种不好的感觉.研究了一下,除了限制坐标轴( Rigidbody---C ...
- Django ajax提交 登录
一.url from django.contrib import adminfrom django.urls import pathfrom appo1 import views urlpattern ...
- 《Python》模块和包
一.模块 1.什么是模块: 一个模块就是一个包含了Python定义和声明的文件,文件名就是模块名字加上.py的后缀. 但其实import加载的模块分为四个通用类别: 1.使用Python编写的代码(. ...