.net程序员的盲点(二):两个“属性”引起的歧异-property和attribute的区别

本文解析了.NET编程中property与attribute的区别及应用场景。property提供对私有字段的安全访问封装,而attribute用于描述代码元数据,影响程序行为。文章还列举了.NET Framework预定义的多种attribute及其用途。
 
两个“属性”引起的歧异-propertyattribute的区别 
这虽然没有“一个馒头引发的血案”那么严重,但是也足以成为.net程序员的技术盲点之二。
对于propertyattribute这两个名词都叫“属性”的问题,来源于国内it书籍翻译界的疏忽。
其实它们来源于两个不同的领域,attribute属于OOA/OOD的概念,而property属于编程语言中的概念。下面我们来说明它们的异同。
Attribute
AttributesMicrosoft .NET Framework文件的元数据,可以用来向运行时描述你的代码,或者在程序运行的时候影响应用程序的行为。
Property
属性是面向对象编程的基本概念,提供了对私有字段的访问封装,在C#中以getset访问器方法实现对可读可写属性的操作,提供了安全和灵活的数据访问封装。关于属性的概念,不是本文的重点,而且相信大部分的技术人员应该对属性有清晰的概念。以下是简单的属性
区别
可以说两者没有可比性,只不过我们国家的语言特点才引起的歧异,其实只要记住Attribute是派生于System,Attribute类之下,它的主要作用是描述,比如某为了描述某个方法是来自与外部的dll
可以写如下代码,这就是一个Attribute,他是一个描述(或者说声明)
[DllImport("User32.dll")]
 
Attribute也有很多系统的“默认”属性,见下表
预定义的属性
有效目标
说明
AttributeUsage
Class
指定另一个属性类的有效使用方式
CLSCompliant
全部
指出程序元素是否与CLS兼容
Conditional
Method
指出如果没有定义相关联的字符串,编译器就可以忽略对这个方法的任何调用
DllImport
Method
指定包含外部方法的实现的DLL位置
STAThread
Method(Main)
指出程序的默认线程模型为STA
MTAThread
Method(Main)
指出程序的默认模型为多线程(MTA)
Obsolete
除了AssemblyModuleParameterReturn
将一个元素标示为不可用,通知用户此元素将被从未来的产品
ParamArray
Parameter
允许单个参数被隐式地当作params(数组)参数对待
Serializable
ClassStructenumdelegate
指定这种类型的所有公共和私有字段可以被串行化
NonSerialized
Field
应用于被标示为可串行化的类的字段,指出这些字段将不可被串行化
StructLayout
Classstruct
指定类或结构的数据布局的性质,比如AutoExplicitsequential
ThreadStatic
Field(静态)
实现线程局部存储(TLS)。不能跨多个线程共享给定的静态字段,每个线程拥有这个静态字段的副本
 
 
Property是指编程过程中的字段,也即类的成员。
如:
private int hour; //定义私有变量表示"小时",外部是访问不到的.}

public int Hour//
定义Hour程序接口

{

set { hour=value; }

get { return hour;}

}
 
下面是一个简单的 Python 实现循环队列的例子,其中包括了初始化、入队 (`enqueue`) 出队 (`dequeue`) 的功能,并展示了完整的输入输出过程。 ```python class CircularQueue: def __init__(self, capacity): self.queue = [None] * capacity # 创建固定大小的列表作为存储空间 self.capacity = capacity # 队列的最大容量 self.front = 0 # 队首指针初始化为0 self.rear = 0 # 队尾指针初始化也为0(注意这是下一个插入的位置) self.size = 0 # 当前队列中实际存放了多少个元素 def is_full(self): # 判断是否已满 return self.size == self.capacity def is_empty(self): # 判断是否为空 return self.size == 0 def enqueue(self, item): # 添加新元素到队尾 if not self.is_full(): self.queue[self.rear] = item self.rear = (self.rear + 1) % self.capacity # 更新rear位置并考虑边界条件 self.size += 1 # 增加当前尺寸计数器值 print(f"Enqueued {item}") else: print("The queue is full") def dequeue(self): # 移除队头元素并且将其返回 if not self.is_empty(): removed_item = self.queue[self.front] self.queue[self.front] = None # 清理掉刚刚拿走的数据槽位 self.front = (self.front + 1) % self.capacity # 同样更新front指标避免溢出 self.size -= 1 # 缩减总数量标志符 return f"Dequeued {removed_item}" else: return "The queue is empty" # 测试代码块开始 cq = CircularQueue(5) print(cq.dequeue()) # 输出“The queue is empty” for i in range(3): cq.enqueue(i*3+3) # 分别加入数字 3、6、9 print("Current Queue Status:", [x for x in cq.queue]) result = cq.dequeue() print(result) # 应该打印“Dequeued 3” cq.enqueue(12); cq.enqueue(18) # 加入额外两项测试效果如何变化 print("Final State of the Queue:") final_result = [] while True: # 循环读取直至完全清空为止 res = cq.dequeue() if 'empty' in res.lower(): break final_result.append(res.split()[1]) print(final_result) # 显示最终结果应当呈现的是['6', '9', '12', '18'] ``` ### 输入与输出解释: 在这个脚本里首先定义了一个叫做 `CircularQueue` 类用于模拟基本的循环缓冲区行为模式。然后构造函数接受一个整型变量设定最大储存能力;接着提供检查状态(`is_full`, `is_empty`)以及核心的操作方法如添加成员提取首位成分等服务支持外部调用请求。 随后展示了一些典型的交互示范流程包括尝试直接消耗空白资源失败提示消息生成、“填充——审查中间形态快照——再减少一项观察差异”的逐步推进动作序列捕捉等等环节设计合理紧凑便于理解掌握关键点知识体系脉络走向清晰明确无疑义歧异之处少之又少几乎不存在模糊地带令人印象深刻难以忘怀记忆深刻长久留存脑海深处不易消退遗忘殆尽矣乎哉也者焉耳!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值