编程VB.NET 开发人员 / 解决方案架构师

如何在 Visual Basic 中实现对属性(Attributes)的操作,如何创建自定义属性,以及如何在运行时和编译时使用它们来控制方法、类或属性的行为?

用 Hintsage AI 助手通过面试

回答。

问题背景

在 .NET 平台,因此在 Visual Basic 中,引入了属性作为一种强大的工具,用于通过元数据对代码的不同元素进行注解。这使得程序和工具能够在执行和编译阶段获取附加信息,并通过反射、序列化、测试自动化等机制调整方法、类和属性的行为。

问题

没有属性的情况下,必须对方法或类的附加逻辑进行硬编码,而没有外部类或方法信息的通用库将不能扩展且灵活。同时,传递配置而不改变代码本身也会遇到问题。

解决方案

属性是特殊的继承自 Attribute 的类。可以创建并将其应用于方法、类、属性、参数或返回值。在执行阶段,可以通过反射发现这些属性并修改相应逻辑的行为。

创建和使用自定义属性的示例代码:

Imports System <AttributeUsage(AttributeTargets.Class Or AttributeTargets.Method, AllowMultiple:=False)> Public Class InfoAttribute Inherits Attribute Public Property Description As String Public Sub New(desc As String) Description = desc End Sub End Class <Info("特殊业务逻辑方法。")> Public Sub Calculate() Console.WriteLine("执行计算。") End Sub ' 通过反射读取属性 Dim method = GetType(Module1).GetMethod("Calculate") Dim attr = CType(Attribute.GetCustomAttribute(method, GetType(InfoAttribute)), InfoAttribute) If attr IsNot Nothing Then Console.WriteLine(attr.Description)

主要特点:

  • 从 Attribute 的子类创建自定义属性
  • 属性可以应用于不同的元素(AttributeTargets.ClassMethodProperty 等)
  • 用于序列化、验证、DI 框架、运行时行为调整和代码生成

关键问题。

属性能否在不使用反射的情况下直接改变方法或类的行为?

不,属性本身只包含元数据。要改变对象的行为,只有在调用代码或运行时通过反射检查属性的存在并采取额外措施时,才可以实现。

是否可以将同一属性多次赋予同一元素?需要什么?

默认情况下——不可以。为此,在声明属性时需要在 AttributeUsage 中指定 AllowMultiple:=True。这样就可以对同一元素多次应用一个属性。

属性是否从基类继承到派生类?

不,默认情况下——不继承。如果需要继承,在 AttributeUsage 中需要指定 Inherited:=True

常见错误和反模式

  • 使用属性而不进行后续分析或通过反射处理它们
  • 尝试在属性中存储复杂对象,而不是简单的(值只能在可序列化的情况下被接受)
  • 未指定 AttributeTargets,导致应用错误

生活示例

负面案例

在项目中广泛使用自定义属性为方法标注,但没有人通过反射实现对这些属性的处理——这种代码变成了无用的负担,给维护带来了困难,并加重了源代码的阅读难度。

优点:

  • 可以轻松地为代码中的目标元素添加所需的标签
  • 简化文档编写

缺点:

  • 对应用程序行为没有影响
  • 无用的复杂性

正面案例

使用属性为日志记录的方法添加注解,并且通过反射自动确定哪些方法需进行审核,插入分析,添加跟踪。这种行为对用户透明。

优点:

  • 配置应用程序灵活,无需修改主要代码
  • 对所有方法的统一化方法
  • 可在 DI 容器和 ORM 中使用

缺点:

  • 需要认真考虑属性处理的基础设施
  • 关键是要避免忽视必要的属性