博客
关于我
10.Properties
阅读量:797 次
发布时间:2023-04-04

本文共 1626 字,大约阅读时间需要 5 分钟。

CLR中的属性(Properties)

CLR(常语言运行时)提供了两种类型的属性:

  • 无参数属性(Propertyless properties):称为属性,直接用于数据的封装。
  • 有参数属性(Parameterful properties):在不同编程语言中可能有不同的名称,但它们都用于定义带有参数的属性。

  • 1. 无参数属性(Propertyless properties)

    无参数属性的主要目的是实现数据的封装,避免直接暴露字段,防止代码错误导致对象状态被破坏。这种属性通常用于:

    • 数据封装:确保字段不被公开暴露。
    • 执行某种副作用、缓存值、延迟创建某个内部对象。
    • thread-safe 操作或逻辑字段(如计算值而非直接存储在内存中的值)。

    通过属性,可以定义 getter 和 setter 方法,实现对字段的安全访问。属性可以是只读或可写,通过省略 getter 或 setter 方法来实现。然而,属性的使用会增加编码复杂性,需要编写额外的方法。


    2. 有参数属性(Parameterful properties)

    有参数属性的访问器方法(getter 和 setter)可以接受参数。这些属性通常用于数组或字典的随机访问。例如,C# 中的 Dictionary 类提供了一个带有键的属性,可以通过 [] 运算符访问。

    有参数属性的编译方式与无参数属性类似,编译器会生成相应的 getter 和 setter 方法,并在元数据中记录属性定义。


    3. 自动实现的属性(Automatically Implemented Properties,AIPs)

    C# 提供了简化的语法,允许开发者通过字段直接定义属性,而无需手动编写 getter 和 setter 方法。这种属性被称为自动实现的属性(AIPs)。以下是其特点:

    • 必须是可读和可写的:无法通过 AIP 定义只读或只写的属性。
    • 编译器生成私有字段:字段名由编译器确定,开发者无法直接访问。
    • 必须在构造器中初始化:无法在字段声明时初始化。
    • 可能导致序列化问题:字段名可能随着重新编译而更改,破坏序列化兼容性。
    • 不支持调试断点:无法在 getter 或 setter 方法上设置断点。

    因此,AIPs 适合简单的场景,但在需要更高控制力或可序列化的对象中不推荐使用。


    4. 编译过程

    编译器处理属性的方式:

  • 生成 getter 和 setter 方法:如果定义了相应的访问器。
  • 生成属性定义:在元数据中记录属性的信息。
  • 支持智能字段:属性可以包含逻辑,而不仅仅是字段。
  • C# 提供了对属性的强大支持,开发者可以直接通过属性访问,而无需调用 getter 或 setter 方法。其他语言如果不支持属性,也可以通过调用访问器方法实现相同的功能。


    5. 属性的使用场景

    • 封装字段:将字段暴露为属性。
    • 读写操作:通过属性实现对对象状态的读写。
    • 集合操作:通过索引器实现随机访问或修改集合项。
    • 性能优化:在不影响可读性的情况下,通过属性实现复杂逻辑。

    6. 属性的局限性

    • 理解难度:属性看起来像字段,但实际上是方法,容易导致混淆。
    • 性能差异:在调试模式下,属性访问可能比字段慢。
    • 可扩展性:某些场景下,方法更适合(如 thread-safe 操作或远程访问)。

    7. 属性的最佳实践

    • 提供默认值:如果属性是可写的,确保有默认值或初始化逻辑。
    • 避免过度封装:仅封装真正需要保护的字段。
    • 使用可读性优先:如果属性的行为可以通过方法实现,选择方法以提高可读性。

    8. 属性的性能

    • JIT 编译:属性访问器方法会被内联,提升性能。
    • 调试模式:属性访问在调试模式下会有性能开销,建议在发布模式下使用。

    9. 属性的元数据

    属性的元数据由编译器生成,包含:

    • getter 和 setter 的方法。
    • 属性的类型。
    • 访问器的访问级别。

    通过以上内容,希望对 CLR 中的属性(properties)有了清晰的理解。

    转载地址:http://eirfk.baihongyu.com/

    你可能感兴趣的文章
    mysql 数据库存储引擎怎么选择?快来看看性能测试吧
    查看>>
    MySQL 数据库操作指南:学习如何使用 Python 进行增删改查操作
    查看>>
    MySQL 数据库的高可用性分析
    查看>>
    Mysql 数据库重置ID排序
    查看>>
    Mysql 数据类型一日期
    查看>>
    MySQL 数据类型和属性
    查看>>
    mysql 敲错命令 想取消怎么办?
    查看>>
    Mysql 整形列的字节与存储范围
    查看>>
    mysql 断电数据损坏,无法启动
    查看>>
    MySQL 日期时间类型的选择
    查看>>
    Mysql 时间操作(当天,昨天,7天,30天,半年,全年,季度)
    查看>>
    MySQL 是如何加锁的?
    查看>>
    MySQL 是怎样运行的 - InnoDB数据页结构
    查看>>
    mysql 更新子表_mysql 在update中实现子查询的方式
    查看>>
    MySQL 有什么优点?
    查看>>
    mysql 权限整理记录
    查看>>
    mysql 权限登录问题:ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)
    查看>>
    MYSQL 查看最大连接数和修改最大连接数
    查看>>
    MySQL 查看有哪些表
    查看>>
    mysql 查看锁_阿里/美团/字节面试官必问的Mysql锁机制,你真的明白吗
    查看>>