【C#学习笔记】属性和字段

在这里插入图片描述

文章目录

  • 前言
  • 属性和字段的区别
    • 字段
      • 访问修饰符和关键字定义
      • 变量类型的定义
      • 变量命名
      • 变量的赋值
    • 属性
  • 不同的使用情况


前言

最近在工作的过程中常常会觉得自己在程序设计方面的能力还是有欠缺。例如一直对于变量的声明感到不足,在工作中为了图方便总是直接public定义字段,实际上造成了很多困扰,特写此文总结一下应当怎样定义成员变量。

属性和字段的区别

字段

【字段】

  • 字段(Field)是一种表示与对象或类关联的变量的成员,字段声明用于引入一个或多个给定类型的字段。字段是类内部用的,private类型的变量(字段),通常字段写法都是加个"_"符号,然后声明只读属性,字段用来储存数据。
public int Index = 0;
private int m_index;
private static int s_index;
public static int s_Index;

字段,或者说变量是类中最基本的要素。一般来说我们定义一个字段的时候,需要考虑的是以下几点:

  • 使用何种访问修饰符
  • 是否使用其他关键字
  • 定义的变量类型
  • 变量名的取名
  • 变量在定义时的赋值

以上要素对于属性定义也是一样的。

访问修饰符和关键字定义

这里这介绍一些常用的:

当我们希望一个字段可以被其他类访问时,通常会将其定义为public,若不希望被其他类访问,则为private,若想要被子类访问,则会定义为protected

然后是一些关键字的运用:若想要即使生成了多个类,但其中的一些字段值依旧全局唯一,我们会使用static来定义。

如果我们想要对字段值在方法中进行类似指针的赋值引用,会用到ref,in,out关键字,或者直接进行指针引用(指针引用和C相同,但是必须要在unsafe块中进行)。

ref,in,out的共同点是:

  • 需要在方法定义与方法调用处显示的使用关键字。
  • 参数按引用传递,而非值传递。

ref,in,out的不同点是:

  • ref:参数变量需要初始化,参数在方法中可以修改或不修改。
  • out:参数变量无需初始化,参数在方法中必须进行赋值。
  • in:参数变量需要初始化,参数在方法中不能进行修改。

在类中实现方法的时候,我们还会用到abstract关键字,virutaloverride关键字。abstract用于抽象类中定义的抽象方法。而virutal定义了父类虚方法,override则用于继承了该父类的子类中重写同名虚方法和抽象方法。还有sealed关键字用来密封类或者函数,如果类使用了sealed则不可被继承,若函数使用了override sealed来描述则该方法不可再被override重写

关键字还有很多种,例如定义委托的delegate,基本语法的if,else,switch,case,break,continue,等等等等

变量类型的定义

定义的变量类型当然是需要什么定义什么,有些特殊的情况,例如我们在调用class类型的变量时,可以不定义为该class本身的类型:若需要访问其父类中的方法,则可以直接定义为它的父类;若需要访问该类中继承的接口方法,也可以直接定义为它的接口类型。

变量命名

变量名的取名我通常是匈牙利命名法和驼峰命名法相结合:

  • 私有成员变量m_name,例如m_maxNum
  • 公共变量Name,例如MaxNum
  • 常量或宏NAME,例如MAX_NUM
  • 静态变量s_开头,结合公有或私有命名

虽然C#官方推荐私有变量_开头,但是似乎许多宏也是_开头的,为避免不必要的问题,我觉得不用以_开头

从取名上尽量要取得详细,除了一些专用名词如TCP,UDP等等,尽量不要使用首字母大写进行缩写。例如一个TCP的接收消息管理器我会命名为TCP_ReceiveManager,或者一个游戏场景内物体管理器GameSceneObjManager。不要因为嫌麻烦而简化命名

变量的赋值

一些变量在运行时需要提前进行初始化,否则会导致空引用,而一些变量虽然不赋值也可以调用,但往往会导致错误的结果。因此变量初始化的赋值很重要,要么在脚本开始执行时调用一个初始化方法统一分配,要么就直接在字段定义时进行赋值。


属性

【属性】

  • 属性(Property)是另一种类型的类成员,定义属性的目的是在于便于一些私有字段的访问。类提供给外部调用时用的可以设置或读取一个值,属性则是对字段的封装,将字段和访问自己字段的方法组合在一起,提供灵活的机制来读取、编写或计算私有字段的值。属性有自己的名称,并且包含get 访问器和set 访问器。

属性和字段的定义几乎是一模一样的,唯一的不同在于属性提供了get访问器和set访问器。这使得我们可以在为属性进行取值和赋值的时候定义一个自定义的方法。

属性本质上可以看作是字段的一层封装,它的内部包含了一个私有字段,并提供了一个get和set来读写这个私有字段,如下所示:

pulic class User
{private string m_name;//_name为字段public string Name   //Name为属性,它含有代码块{get{return m_name;//读取(返回_name值)}set {m_name= value;//为m_name赋值,value可以直接获取赋值}}
}

所以为什么我们要多一层封装而非直接将字段public出来呢?因为程序设计中我们不希望一个字段可以被其他类轻易的访问,有时我们只想它可读或者可写,或者在读写时进行一些其他操作。如果不用属性则需要定义读写的方法,显然太麻烦了。

使用属性,我们可以用get代表字段可读,set代表可写,以此控制字段的读写权限。同时属性接口是只对外的(对内直接修改字段即可了),我们可以自定义访问器的代码,保证了外部修改的安全性。

所以我们才建议将字段作为类中的私有变量,属性作为公共变量,通过属性的设置,我们既可以灵活的定义读写字段时会发生什么事情,也可以很好的封装字段以实现保护的目的。


不同的使用情况

公共字段:

  1. 允许自由读写
  2. 取值范围只收数据类型约束而无其他任何特定限制;
  3. 值的变动不需要引发类中其它任何成员的相应变化;

如果满足上述情况,则可以自由使用public 的字段,但是还是不建议使用

属性:

  1. 要求字段只能读或只能写;
  2. 需要限定字段的取值范围;
  3. 在改变一个字段的值的时候希望改变对象的其它一些状态;

然而为什么我们建议使用属性而非公共字段,从设计的耦合性和项目的可维护性来举例,假如我们只是公开了这个字段,一旦我们想要修改这个字段的某些处理逻辑,那就必须对每一个引用了该字段的类中都进行处理。而使用属性,我们则只需要设置get方法即可。

实际上属性并不占用内存,只是用起来冗余一点,但是对于工程的提升是实打实的。

并且.net也提供了语法糖,我们只需定义属性即可使用同名字段了(打出prop+回车 自动补全):

public int Index{ get; set; }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/22723.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

声音突破:so 索

小孩儿看完武侠剧,就决定从二楼往地面上跳,年轻的老妈看到了,就在那里骂,喝斥不准逞能,不许乱来,不许跳。但小孩子不听话,心里全是影视剧的画面,那叫一个侠之能也,于是飞…

llvm 常用命令备忘

执行 IR 上的指令合并优化 pass $ opt –S –instcombine testfile.ll –o output1.ll 执行无效参数优化 pass $ opt –S –deadargelim testfile.ll –o output2.ll C 语言生成 IR 文件 $ clang -emit-llvm -S multiply.c -o multiply.ll C 语言生成 IR 文件 $ clang -cc1 -…

面向长文本处理的键值缓存压缩技术:智能压缩,无损性能,免微调

随着输入长度的增加,大型语言模型(LLMs)中的键值(KV)缓存需要存储更多的上下文信息以维持性能,这导致内存消耗和计算时间急剧上升。KV缓存的增长对内存和时间效率的挑战主要表现在两个方面:一是…

使用JavaScript实现网页通知功能

如何使用js来实现网页通知功能。即使在用户浏览其他页面时,也能向他们推送通知信息。 废话不多说直接上代码 function showAutoNotification() {if ("Notification" in window) {Notification.requestPermission().then(function(permission) {if (permis…

元宇宙数字藏品交易所,未来发展的大趋势

随着科技的飞速进步,元宇宙以其独特的魅力为数字世界绘制了一幅前所未有的宏伟蓝图。在这一宏大的背景下,数字藏品交易所作为连接虚拟与现实的桥梁,正以其卓越的优势,引领着数字藏品市场迈向新的高度。 首先,元宇宙为…

Vue 的服务端渲染(SSR)有哪些钩子可以用

在 Vue 的服务端渲染(SSR)过程中,并不会执行完整的生命周期钩子,只有一部分钩子会在服务器端执行。以下是 Vue SSR 中支持的生命周期钩子: beforeCreate:在实例初始化之后,数据观测 (data obser…

【ARM Cache 与 MMU 系列文章 7.8 – ARMv8/v9 MMU Table 表分配原理及其代码实现 2】

文章目录 MMU Table 表分配原理及其代码实现MMU Table 分配代码实现MMU Table 表分配原理及其代码实现 在做映射的时候所映射的地址范围最大只能是某一级 level table 中 entry 所能支持的最大范围,如果超过这个范围需要在对应 level table 中新增一个entry,这里还是以映射虚…

【相关概念】经济金融中的Momentum

张张张三丰de思考与总结: 最近做的期货价格泡沫中,一直在说,momentum,momentum,momentum,那么究竟什么是momentum呢? 目前,在有关期货价格泡沫的研究文献中,一般都是研究…

本轮牛市新趋势,跟随The First捕捉牛市Alpha

与以往牛市“百花齐放”的繁荣景象相比,本轮牛市颇具独特走势,呈现出了资金集中度高、财富聚集效应小的特点,绝大部分加密资产甚至跑不赢BTC的涨幅幅度。而以往大放色彩的公链币价值币的走势,甚至比不过牛尾才爆发的MEME币。这使得…

Java项目之消息队列(手写java模拟实现mq)【三、MQ的核心类-消息类的存储(用文件存储消息)】✔ ★

Java项目之MQ 七. 消息存储设计设计思路为什么要用文件存储文件存储结构queue_data.txt ⽂件格式:queue_stat.txt ⽂件格式: 创建 MessageFileManager 类定义一个内部类, 来表示该队列的统计信息 Stat实现统计⽂件Stat读写(文本文件的读写)InputStream—…

python爬虫入门教程(一)

上一篇文章讲了爬虫的工作原理,这篇文章以后就要重点开始讲编程序了。 简单爬虫的的两个步骤: 使用HTTPRequest工具模拟HTTP请求,接收到返回的文本。用于请求的包有: requests、urllib等。 对接收的文本进行筛选,获取想要的内容。用户筛选文…

JavaScript-内存分配,关键字const

内存空间 内存分为栈和堆 栈:由操作系统自动释放存放的变量值和函数值等。简单数据类型存放在栈中 栈会由低到高先入后出 堆:存储引用类型 (数组,对象) 对象会先将数据存放在堆里面,堆的地址放在栈里面 关键…

【ArcGISProSDK】获取要素中某字段最大值

public static async Task<double> GetMaxValueFromField(string vectorFilePath, string fieldName){double maxValue = 0;//矢量所在文件夹var filePath = System.IO.Path.GetDirectoryName(vectorFilePath);//矢量名称var fileName = System.IO.Path.GetFileNameWitho…

VMD-PSO-LSTM单维时序预测模型(单输入单输出)-附代码

VMD-PSO-LSTM单维时序预测模型&#xff08;单输入单输出&#xff09; 1&#xff09;首先对原始单维数据进行VMD分解&#xff0c;分解为K个模态分量和1个残差分量 2&#xff09;将各个模态分量输入模型&#xff0c;建立模型进行预测 3&#xff09;将各个预测结果相加得到最终…

clickhouse(十五、存储优化实践)

文章目录 背景问题定位优化方式排序键设计写入顺序压缩算法 DoubleDeltaLowCardinality避免使用Nullable 总结 背景 clickhouse集群容量告警&#xff0c;项目中某些表占据大量的存储空间&#xff0c;借此机会对ck的存储优化进行实践学习&#xff0c;并通过多种方式测试验证优化…

设计模式相关更新中

详见gitee: 更新中​ ​​​​​​设计模式相关: 设计模式相关介绍 (gitee.com) 一.面向对象的设计原则 二.单例模式

React(五)useEffect、useRef、useImperativeHandle、useLayoutEffect

(一)useEffect useEffect – React 中文文档 useEffect hook用于模拟以前的class组件的生命周期&#xff0c;但比原本的生命周期有着更强大的功能 1.类组件的生命周期 在类组件编程时&#xff0c;网络请求&#xff0c;订阅等操作都是在生命周期中完成 import React, { Com…

算法题day37日(补5.23日卡:贪心算法day4)

一、刷题&#xff1a; 1.leetcode题目 860. 柠檬水找零 - 力扣&#xff08;LeetCode&#xff09;&#xff08;easy&#xff09;&#xff1a; 我觉得我写的代码有点蠢 class Solution:def lemonadeChange(self, bills: List[int]) -> bool:dict_ {5:0,10:0}if bills[0] !…

Python降维基础知识:深入探索与实战应用

Python降维基础知识&#xff1a;深入探索与实战应用 在数据分析和机器学习的广阔领域中&#xff0c;降维技术一直扮演着重要的角色。Python&#xff0c;作为数据处理和机器学习的首选语言&#xff0c;为我们提供了丰富的降维工具和算法。本文将从四个方面、五个方面、六个方面…

算法训练营第四十九天 | LeetCode 139单词拆分

LeetCode 139 单词拆分 基本还是完全背包的思路&#xff0c;不过用了三重循环&#xff0c;第三重循环是用于判断当前字符串尾部指定长度字符是否和列表中某一字符串相同&#xff0c;是的话可以将当前dp[j]或上当前下标减去该单词长度后的下标值。 代码如下&#xff1a; clas…