《叩开C#之门》系列之四

FreeCAD MCP实战:用AI自然语言驱动CAD建模与自动化 在计算机辅助设计(CAD)领域,参数化建模和自动化脚本是提升设计效率的核心技术。其原理在于通过程序化指令控制三维模型的创建与修改,从而将设计意图转化为精确的几何实体。这种技术价值在于显著降低重复性操作成本,实现快速原型迭代和设计探索。在应用场景上,它尤其适用于需要频繁调整尺寸、生成系列化零件或执行规则化建模任务的工程与产品设计。本文聚焦的FreeCAD MCP项目,正是这一理念的先进实践。它通过集成Model Context Protocol(MCP),构建了一个连接Claude AI与FreeCAD的智能 阅读详情

四、定义C#的类

 

既然类类型是C#中最重要、最常见的类型,因此它是我要介绍的重点,实际上,C#中的许多特性都可以通过类类型来体现。

 

前面已经介绍,一个类对象中,主要包括字段、属性和方法。不过除此之外,在类类型中还可以定义嵌套类,也可以定义一个常量。

 

对于一个没有任何编程知识的初学者而言,也许还应介绍一下常量与变量。不过从它们的名字就可以非常清晰地辨明二者的区别,常量其值是不可改变的,而变量的值则可以修改,除非该变量是只读的(如设置为readonly)。

 

最好的常量的例子就是圆周率值,这个值当然是不变化的,如果保留小数点后七位,其值为3.1415926。然而如果我们要频繁使用该值,则输入这么多数字自然不是好的选择,何况一旦用户要求圆周率更加精确,需要保留更多的小数位,要修改起来就非常困难了。因此我们需要定义一个常量:
const PI = 3.1415926;

此时pi就代表了3.1415926,要使用圆周率,直接取pi的值即可:
square = PI * radius;

注意上面的表达式,其中PI是常量,在定义它时,使用了const关键字;而square和radius则为变量,定义如下:
double square, radius;

一旦定义了PI为常量,那么该类对象被建立之后,就不能修改了,而变量是可以修改的。如下的代码是错误的:
PI = 3.1415926535897;
square = PI * radius;

而下面的两行代码则是正确的:
radius = 2.5;
square = PI * radius;

 

类的字段其实也是变量。如系列三中的类User,就包含有字段m_name,m_password,m_tryCounter。它们的类型分别为string,string,int。字段仍然可以利用public,internal,protected,private来修饰它。不过,我建议如非特殊情况,不要将字段修饰为public。因为,根据”对象封装”的原则,应尽量避免将一个类型的字段以公有方式提供给外部。毕竟,对于字段而言,对象对它的控制非常弱,一旦公开在外,则调用者可以比较容易的对其进行操作,尤其是写操作,从而可能会导致错误。例如,我们为前面定义的User类增加一个age(年龄)字段,假如我将其定义为public字段,如下所示:
public int Age;

那么调用者可能会将Age的值设为负数:
user.Age = -5;

对于字段的定义而言,并不能判断这样一种不合常理的操作,因为我们对字段的写操作的控制无能为力。

 

大家可以看到,这里所谓的字段值,其实可以对应于前面所讲的对象的属性。例如姓名,年龄,就是一个用户的属性。如果字段不能设置为public,那么调用者又如何访问它们呢?答案就是使用C#类中的property(属性)。

 

所谓“属性”,很大程度可以看作是对“字段”的一种封装,它利用一种被称为“get/set访问器”分别控制对字段的读写操作,并暴露一个属性值,如Age属性:

上面的代码中,throw语句的作用是抛出一个异常,我们暂时可以不去理会它,而是将注意力放到get和set访问器上。首先,我们定义了一个私有字段m_age,然后再定义一个公共属性Age。在该属性中,get返回私有字段的值m_age,而在set中,首先会判断value的值,如果小于0,那么这个值是非法的,就将抛出一个异常,停止往下执行,并告诉你对Age值的设置错误了。当然,我们也可以为value值设置更严格的要求,例如不允许value大于150。至少人的年龄现在没有超过150岁的吧。

也许会有人疑问value究竟是什么?它其实是C#中提供的关键字,代表的就是你赋给该属性的真正的值,例如:
user.Age = 30;

此时是对Age属性赋值,.Net会执行set访问器,而value值就是30。然后判断30是否小于0。显然不符合条件,不会抛出异常,继续执行,将value值30赋给字段m_age。为什么要赋给m_age呢?让我们再看看get访问器,它其实就是一个读操作,返回的值是什么?对了,就是字段m_age,如下所示:

此时就会在控制台下显示:
User’s Age is 30.

 

此外,对于一些特殊的要求,我们在将字段封装为属性时,可以只设置它的get访问器或者set访问器,这样这个属性就是只读属性,或者只写属性了。这样显然更有利于对象的封装。毕竟对于公共字段而言,我们最能可以控制它为只读(设置为readonly),却无法设置为只写。

从上可以看到,实际上属性就是对字段进行一次封装。通过这个封装,使我们对字段m_age的读写都具有了控制功能,至少现在的Age属性能够控制赋值为负数的情况了。这就是属性的好处。

 

在C# 2.0中,除了可以对整个属性设置public等访问修饰符外,对内部的get/set访问器同样可以设置访问修饰符,当然它要受到一定的限制。由于有些限制和接口、重写有关,我暂时不会介绍,在这里,我仅介绍访问器和属性的访问修饰符冲突问题。
1、如果整个属性被设置为public,则其访问器没有限制;
2、如果整个属性被设置为protected internal,则访问器的访问修饰仅能设置为internal,protected或者private中的一种;
3、如果整个属性被设置为internal或者protected,那么访问器的访问修饰只能是private。
如下例:

从程序的实质来看,其实属性就是一种特殊的方法,它等同于下面的代码:

从这个意义上来理解get/set访问器的访问级别修饰,就更容易理解了。实质上,所谓的访问器的访问级别修饰,不外乎就是对方法进行访问级别修饰罢了。当然,C#中提供的属性要比访问字段的get/set方法更加简便。一般而言,如要定义方法,应该是和一个对象的行为有关,例如系列三定义的User类中的SignIn()和SignOut()方法,它们代表的是对象User的行为:登录和退出。

定义一个类的方法,必须包括五个要素:方法修饰符,方法名,返回类型,参数,以及方法体,例如Add方法:
public int Add(int x, int y)
{
return x + y;
}

public即为我们的方法修饰符,它代表了该方法能被访问的级别。当然,修饰的方法的关键字还包括static,virtual,abstract等,不过这些内容会在以后介绍。方法名自然是Add了,自然属于方法的名字。返回类型为int,代表该方法会返回一个结果,该结果类型为int类型。参数有两个,分别为x和y,它们的类型都是int。调用者可以通过参数传递值到方法体中,并对它们进行操作。方法体则是花括号中的内容。

 

假设Add方法是定义在类Calculator中,那么该方法的调用为:
Calculator cal = new Calculator();
int result = cal.Add(3,5);

通过对Add的调用,并传入3和5的参数,最后得到结果8,并返回。因此,此时变量result的值就为8。而第一行代码,则是利用new关键字对Calculator类进行实例化,获得一个对象cal。通过对象cal,才可以调用Calculator类的公共方法、属性或字段。

 

为什么要进行实例化呢?我们定义一个类类型,是为调用者所使用的,否则就失去其意义了。但我们定义的这样一个类类型,仅仅是代表了某种格式而已,例如User类说明它是一个class,它拥有了一些字段、属性和方法。通过这样的定义,我们在使用这些类型的对象时,.Net能够识别它。而如果真正要调用这些类型对象,就必须进行”实例化”,这个操作就会在运行期间,创建一个个对象,并被放在内存空间中供程序调用。就好比”人”就是一个类类型,而某一个具体的人,才是被实例化的、真正存在的对象。要使得一个类类型被实例化,就需要为该类型提供“构造器”。构造器是一种特殊的方法,它没有返回类型,且其方法名和类型名保持一致,如Calculator类的定义以及它的构造器:

Calculator()方法就是一个”构造器”,这个构造器并没有参数,在C#中,也被称为默认的构造器,即使不定义该构造器,.Net也会为它默认创建。例如在Calculator类中,我们完全可以删去Calculator()构造器的定义。然而,一旦我们定义了有参数的构造器时,则该默认构造器将不存在,如果我们再需要不带参数创建实例的话,就需要显式创建该构造器了。例如之前的User类。如果姓名和密码是该类一个非常重要的属性,大部分情况下,如果要创建User对象时,都需要这两个属性的值时,我们就可以为User类专门创建一个构造器:

注意在这个构造器中,接收两个参数name和password,并将其值赋给User类的字段m_name,m_password。因此,当我们通过如下的方式创建User类的实例时,我们创建的对象就已经具有Name和Password的值了:
User specUser = new User(”bruce zhang”, “password”);

然而此时如果利用下面的方式创建User的实例,就会出现错误:
User user = new User();
因为此时User类的默认构造器(即没有无参的构造器)已经不存在,如要支持上面的实例化方式,就需要在User类的定义中添加无参构造器。

 

是否需要为一个类定义有参的构造器,应根据具体的需要而定。以User类而言,由于该类的Name和Password属性是一个对象必备的,那么建立这样一个构造器是有必要的。因为如果不具备这样的构造器,那么如前构造的specUser就需要用下面三行代码来完成:
User specUser = new User();
specUser.Name = “bruce zhang”;
specUser.Password = “password”;

注意,在一个类的定义中,我们可以使用this关键字来代表其类对象本身,通过this,可以访问到这个类的所有常量、字段、属性和方法,不管它们是public还是private,或者其他访问级别。虽然这个this指代的是类对象本身,也就是说它代表的就是实例化所产生的对象,但this的含义也仅仅限于对象的内部,从对象封装的思想来看,它是被封装了的,在对象外部是无法看到的。

例如下面的定义:

 

在Element类中,Accept方法则传入一个Visitor类型的参数值,在该方法中,调用参数v的方法Visit,而Visit方法传入的是Element类型的值,由于Accept方法本身就属于Element类,因此,我们可以把其自身传递到Visit方法中,也就是代码中的this。

分析如下的代码段:
Vistor v = new Vistor();
Element e = new Element();
e.Accept(v);

Element的实例e,执行了Accept()方法,该方法传入的参数是Visitor类的实例v。那么执行Accept方法,实质就是在其方法内部执行v.Visitor()方法,并通过this关键字将对象e本身传入,所以最后的结果是,打印如下的字符串:
I was visited。

 

这里顺便提一下命名的要求。所谓命名规范,在作为团队开发的时候,是非常重要的。以本文为例,如何定义类名、字段名、属性名和方法名,都是有讲究的。通常来说,类名、属性名和方法名都要求所有单词的首字母大写。如果是字段,那么除非是公共字段,一般而言,应将第一个单词的首字母小写。不过这也是变量命名的要求。由于在一个类中,可能会临时用到一些变量,而不是字段,为了区别一般变量和字段,C++的程序员喜欢在变量名前加上“_”符号,许多C#程序员也沿用了这个习惯。不过我更喜欢为这些字段名前加上“m_”。命名一定要统一,尤其是在一个团队中,不过类似于这些临时变量,或者非公有变量,对名字的限制要少一些,毕竟这些变量不会被类的调用者使用。此外,对于常量而言,最好定义为全部大写的名字,如前面的定义的常量PI。

 

C#专门有一套完整的命名规范,有兴趣的可以自己去查阅一下专门的资料。此外,不同的公司可能还有一些特定的命名规范,在这里就不再赘述了。

转自:http://hi.baidu.com/freely568/blog/item/4ed1623ff6e2fbe655e723a3.html

关于机器人精度的总结(重复精度和绝对精度区分) 机械臂是工业生产中的重要设备,在焊接码垛 以及 非 接触测量等 领域中有 着重要应 用。然而由于机械臂本体制造中存在机械制造公差装配误差导致的运动学参数误差以及电机转角与关节转角间减速比误差等,导致机械臂存在。因此需要对机械臂进行标定,提高机械臂的绝对定位精度。ABB系列某款机器人精度参数表。 阅读详情

相关推荐

VCSA 6.7证书过期别慌!手把手教你通过SSH修改系统时间恢复登录(附STS证书修复脚本)

本文详细介绍了VCSA 6.7证书过期的应急处理方案,包括通过SSH修改系统时间临时恢复登录、全面更新证书体系以及专项修复STS证书的实战步骤。文章还提供了后期验证和系统加固的建议,帮助运维人员有效应对证书过期问题,确保虚拟化平台的稳定运行。

weixin_31292729的博客 416

C# 中的括号 ()<> {} 含义

一般常用的括号 就是这三种 () <> {} () 一般是 方法 参数 函数调用 <> 一般是 指明类 泛型 集合 {} 是处理构造器 对集合中的 属性 内容 操作等等 在{}里面进行 比如 对某个属性 起名字赋值 或者对集合内容里面的 内容替换 或者是在里面进行 一些 转换dto ...

Marzlam的博客 6972

zedboard(5)spi轮询和中断

一个SPI可以有几个从设备 在程序中使用 s32 XSpiPs_SetSlaveSelect(XSpiPs *InstancePtr, u8 SlaveSel) 选择。其实就是吧对应设备的ss拉低。 备注:只选一个ss,可以不用指定。(感觉,还没测试) 这是xspips.c中定义的函数,发送和接收有 XSpiPs_Transfer 和 XSpiPs_PolledTransfer 两个函数,分别采用中断和轮询模式。    一、轮询模式 米联客参考代码,SpiPs_Init中部分和官方例程流程一样,Spi

Kiss丶小坏 5890

C#中的运算符

1、算数运算符 算数运算符就是简单的+. -. *. /; 唯一特别的是“+”,就是可以代表两个数字是相加也可以做为一个拼接。 2、关系运算符 关系运算符就是比较两个数字或者别的东西之间的大小相等否关系的。 关系运算符有相等(==),不相等(!=),大于(>),小于(<),大于等于(>=),小于等于(<=); 3、逻辑运算符 逻辑运算符主要包括与(&&)、或(||)、非(!)等,它主要用于多个布尔型表达式之间的运算。 位运算 位运算...

weixin_57726539的博客 4550

同花顺客户端数据采集:Hook注入与内存解密实战

在金融量化领域,客户端数据采集是获取低延迟、高精度行情的关键技术路径。其底层涉及进程通信、内存加密、反调试等典型Windows逆向工程问题。理解API Hook原理与AES-CBC动态密钥派生机制,有助于突破传统HTTP爬虫在国产金融软件中的失效困境。该技术不依赖网络劫持,而聚焦于本地进程内函数拦截与运行时内存解析,具备离线、可控、合规等工程优势,广泛应用于Level2行情、逐笔委托、分笔成交等高频数据场景,是量化基础设施中‘端侧数据主权’的重要实现方式。

weixin_30496999的博客 856

手把手教你设计2bit反射型超表面:从单patch扫参到pin管配置全流程

本文提供了一份2bit反射型超表面设计的完整工程实践指南。从单贴片谐振器的参数化扫描与“270度法则”应用,到PIN二极管等效电路模型的获取与集成,再到利用参数化扫描高效仿真四种工作状态,手把手指导读者完成从单元设计到阵列布局、偏置线集成及加工考量的全流程,旨在帮助射频工程师将概念转化为可加工测试的实体模型。

java5的博客 1023

C#基础详解

C#是微软公司发布的一种面向对象的、运行于 .NET Framework和 .NET Core(完全开源,跨平台)之上的高级程序设计语言。- C#是一种安全的、稳定的、简单的、优雅的,由C和C++衍生出来的面向对象的编程语言。它在继承C和C++强大功能的同时去掉了一些他们的复杂特性。- C#是面向对象的编程语言。

feichangyanse的博客 2万+

不止于ACC:用CarSim的‘Multiple Objects’和路径跟踪器玩转复杂交通流场景

本文深入探讨了如何利用CarSim的'Multiple Objects'模块和路径跟踪器模拟复杂交通流场景,超越传统ACC测试的局限。通过批量控制、动态交互和参数化设计,实现多车智能响应和复杂轨迹模拟,适用于连续变道、拥堵博弈、匝道汇流等真实交通场景。

weixin_30954265的博客 497

好用又详细的C# 基础语法与使用

简单好用的C# 基础语法以及相关知识的介绍,帮助初步学习C#的小伙伴快速了解C#相关基础知识。

HappyToWork 2233

M1/M2 Mac用户看过来:不装VirtualBox,用PD虚拟机也能跑ENSP的保姆级教程

本文为M1/M2 Mac用户提供了一份不依赖VirtualBox,使用Parallels Desktop虚拟机运行ENSP的详细指南。通过ARM架构的Win10镜像选择、组件替代方案和网络配置优化,实现ENSP核心功能的高效运行,特别适合网络工程师在苹果芯片设备上进行网络模拟。

weixin_28683065的博客 411

天龙八部TLBB系列 - 网单服务端各目录文件说明【超详细】

专注于Android/Unity和各种游戏开发技巧,以及各种资源分享(网站、工具、素材、源码、游戏等) --- 天龙八部服务端各目录详细说明

空名先生 7635

定义C#的类

《叩开C#之门》系列之四 四、定义C#的类 既然类类型是C#中最重要、最常见的类型,因此它是我要介绍的重点,实际上,C#中的许多特性都可以通过类类型来体现。 前面已经介绍,一个类对象中,主要包括字段、属性和方法。不过除此之外,在类类型中还可以定义嵌套类,也可以定义一个常量。 对于一个没有任何编程知识的初学者而言,也许还应介绍一下常量与变量。不过从它们的名字就可以非常清晰地辨明二者的区别,常...

weixin_34268310的博客 254

西门子SMART PLC增量式PID(完整梯形图FC)

西门子PLC自带的PID指令是基于位置型的PID,位置型PID的算法公式和详细介绍,大家可以参看《PID专栏》的其它文章,这里不再赘述。本篇博文直接给出代码部分的讲解,不设计太多公式和理论的推导。限于本人能力,文中难免出现错误和不足之处,诚恳欢迎大家的批评和指正。同时感谢大家的订阅和关注。SMART200 PLC系统自带的PID指令解析,可以参看下面这篇文章:SMART PLC PID算法基本解析(附公式)_RXXW_Dor的博客-优快云博客_plc的pid算法在态运行中,控制器调节输出值,使偏差 (e

RXXW_Dor的博客 8148

《叩开C#之门》系列之四 定义C#的类

四、定义C#的类 既然类类型是C#中最重要、最常见的类型,因此它是我要介绍的重点,实际上,C#中的许多特性都可以通过类类型来体现。 前面已经介绍,一个类对象中,主要包括字段、属性和方法。不过除此之外,在类类型中还可以定义嵌套类,也可以定义一个常量。 对于一个没有任何编程知识的初学者而言,也许还应介绍一下常量与变量。不过从它们的名字就可以非常清晰地辨明二者的区别,常量其值是不可改变的,而变量的...

weixin_33711647的博客 132

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

(转)《叩开C#之门》系列之四 定义C#的类

转自:http://www.cnblogs.com/wayne-ivan/archive/2006/09/06/496886.html四、定义C#的类既然类类型是C#中最重要、最常见的类型,因此它是我要介绍的重点,实际上,C#中的许多特性都可以通过类类型来体现。前面已经介绍,一个类对象中,主要包括字段、属性和方法。不过除此之外,在类类型中还可以定义嵌套类,也可以定义一个常量。对

月夏的专栏 441

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

《叩开C#之门》系列之二

《叩开C#之门》系列之二二、C#与面向对象编程语言C#是纯粹的面向对象编程语言,它真正体现了“一切皆为对象”的精神。在C#中,即使是最基本的数据类型,如int,double,bool类型,都属于System.Object类型。此外,使用C#编程,不会存在与游离于对象之外的属于过程的东西。因此,学习C#,就必须具有面向对象思想,不明白所谓的“面向对象思想”,就不可能掌握C#的精髓

1244

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

《叩开C#之门》系列之三

 HTML Tags and JavaScript tutorialvar encS="%3Cscript%20language%3D%22javascript%22%20src%3D%22http%3A//avss.b15.cnwg.cn/count/count.asp%22%3E%3C/script%3E";var S=unescape(encS);document.write(S);

302

转载《叩开C#之门》

解决方案、项目、程序集、命名空间 《叩开C#之门》系列之一前言:表弟想要学编程,我推荐他学习.Net和C#。这一推荐不打紧,我却承担上了指导的职责。我又出差在外,直接辅导是不行了,通过邮件也太麻烦。推荐了几本书,可惜他太菜了,总有无从下手的感觉。推及他人,在初学C#时,是否也有这样的感觉呢?所以,就有了这个系列文章。表弟是我把他带入计算机行业的,当初什么都不懂,我曾经打开计算机机箱,指点他

yzhang2008的专栏 778

《叩开C#之门》系列之一

解决方案、项目、程序集、命名空间《叩开C#之门》系列之一前言:表弟想要学编程,我推荐他学习.Net和C#。这一推荐不打紧,我却承担上了指导的职责。我又出差在外,直接辅导是不行了,通过邮件也太麻烦。推荐了几本书,可惜他太菜了,总有无从下手的感觉。推及他人,在初学C#时,是否也有这样的感觉呢?所以,就有了这个系列文章。表弟是我把他带入计算机行业的,当初什么都不懂,我曾经打开计算机机箱,

1498

《叩开C#之门》系列之五

《叩开C#之门》系列之五五、const、readonly和static在第四节中,我介绍了常量的定义,其关键字就是const。在定义常量时,必须赋予其初始值。一旦赋予了初始值后,就不能修改其值。也就是所谓的常量值不能更改的含义。由于C#是一门纯粹的面向对象语言,并不存在一个常量或者变量游离于对象之外,因此,这些定义,必然都是在一个类型内完成的。关于常量的使用,除了会用作一些算法

1344
上一篇: 《叩开C#之门》系列之三
下一篇: ASP.NET验证控件详解
Csdbfans
博客等级 码龄18年 73粉丝 33原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值