C#中的属性

简介: C#中的属性

目录

什么是属性(Attribute)

自定义属性

如何使用属性

限制属性使用范围

如何访问属性

反射访问

总结


这篇文章主要面向的对象是初级开发人员,以及对属性不是很熟悉的开发人员。

什么是属性(Attribute)

属性在C#中很常用,但有部分开发人员对它既熟悉又陌生。概念上属性是将元数据关联到元素的方式。属性的使用方法我们在代码中经常肩见到,比如下面这样的:

[Test]
public class MyClass
{
   //more code
}

在上面的样例代码中Test就是一个属性。属性是放在类、字段和方法等定义的前面(上面),用来指定特定内容的。.Net框架中为我们提供了一些常用属性。比如Serializable,它告诉编译器当前类可以序列化成JSON或XML。


TIP:属性在编译的时候会嵌入到程序集中。我们可以使用反射来获得属性的值。


自定义属性

当.Net框架提供的属性不足以满足我们开发的要求时,我们可以自定义属性,自定义属性在项目中算比较常用的技术。定义自定义属性需继承抽象类System.Attribute。比如当创建一个汽车类,需要一个属性来表示汽车的品牌、型号时,我们可以像下面代码这样实现自定义属性:

public class CarAttribute : Attribute
{
    public string Brand { get; set; }
    public string Model { get; set; }
    public CarAttribute (string brand, int model)
    {
        Brand = brand;
        Model = model;
    }
}

通过上面的代码我们可以看出,属性其实就是一个类,它和其它类一样,也拥有字段、方法、构造函数等成员。

如何使用属性

在本文的前面说过,属性可以放在类、字段和方法等定义的前面(上面),那么,我们来看一下如何使用上一小节中自定义的属性,代码如下:

[Car("BMW", "x3")]
public class Carriage
{
  //more code
}

在这里这儿需要注,自定义属性的名字,如果我使用的是xxx+Attribute的形式来命名名称的话,那么在使用时可以用短名称xxx(例如上面代码中的Car就是使用的是CarAttribute的短名称)


限制属性使用范围

属性本身是一个类,因此属性也可以用其他属性来指定和修饰。常用的修饰属性的属性是AttributeUsage 属性,它用来限制自定义属性可以修饰的元素类型,例如我们将CarAttribute属性的使用范围限制为类和接口,可以这么做:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]
public class CarAttribute: Attribute 
{
  //more code
}

AttributeUsage属性的参数AttributeTargets是一个枚举,包括类、接口、方法、构造函数、枚举、程序集等枚举内容。经过修改后的CarAttribute属性只能用在类和接口中,如果用它来修饰字段,编译器就会报错。

AttributeUsage还允许我们定义从修饰对象继承的对象,是否也获得该属性。同样我们将CarAttribute修改为从修饰对象继承的对象可以获得该属性:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, Inherited = true)]
public class CarAttribute: Attribute 
{
  //more code
}

同时我们也能指定属性是否可以在一个元素上有多个实例,例如下面的代码就定义了CarAttribute属性不允许在一个元素上有多个实例:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
public class CarAttribute: Attribute 
{
  //more code
}

如何访问属性

到这里一定有小伙伴问,如何访问属性呢?其实.NET框架为我们提供了Attribute.GetCustomAttribute()方法来访问属性,简单的用法如下:

var carType = typeof(Carriage);
var attributeType = typeof(CarAttribute);
var attribute = (CarAttribute)Attribute.GetCustomAttribute(carType , attributeType);
Console.WriteLine($"Car is {attribute.Brand} {attribute.Model}");

反射访问

除了上面的访问方式外,还有一种常用的访问方式:反射访问。反射的主要的作用是用来收集对象的数据而不是对象本身的数据。这些数据包括对象的类型、对象的成员的信息、特定程序集信息以及存储在元素属性中的任何信息。最简单的反射是GetType()方法,代码如下:

int myNum= 88;
Type type = myNum.GetType();
Console.WriteLine(type);

我们还可以使用反射来获取关于包含给定类型的程序集的信息:

Assembly mobileAssembly = typeof(Carriage).Assembly;
Console.WriteLine(mobileAssembly);

反射同样可以获得属性的信息和对象构造函数的信息:

PropertyInfo property = reflected.GetType().GetProperty("PropertyOne");
Console.WriteLine(property);
ConstructorInfo constructor = reflected.GetType().GetConstructor(new Type[0]);
Console.WriteLine(constructor); 

总结

属性将元数据分配给类、字段、方法等。元数据在构建项目时被编译并描述元素而不是元素的数据。我们可以继承Attribute类来自定义属性,并使用AttributeUsage属性限制属性的使用范围,并通过反射来获取属性数据。

目录
相关文章
|
6月前
|
存储 安全 编译器
C# 11.0中的泛型属性:类型安全的新篇章
【1月更文挑战第23天】C# 11.0引入了泛型属性的概念,这一新特性为开发者提供了更高级别的类型安全性和灵活性。本文将详细探讨C# 11.0中泛型属性的工作原理、使用场景以及它们对现有编程模式的改进。通过深入了解泛型属性,开发者将能够编写更加健壮、可维护的代码,并充分利用C#语言的最新发展。
|
C# Windows 容器
C#或Winform中的消息通知之系统托盘的气泡提示窗口(系统toast通知)、ToolTip控件和ToolTipText属性
NotifyIcon控件表示系统右下角任务栏上的托盘图标,其ShowBalloonTip方法用于显示气球状提示框(Win10只有为本地Toast通知),ToolTip\oolTipText可以...
1964 0
C#或Winform中的消息通知之系统托盘的气泡提示窗口(系统toast通知)、ToolTip控件和ToolTipText属性
|
2月前
|
安全 C# 索引
C#一分钟浅谈:属性与索引器的定义
本文深入浅出地介绍了C#编程中的属性和索引器。属性让字段更安全,通过访问器方法在读写时执行额外操作,如验证数据有效性;索引器则赋予类数组般的访问方式,支持基于索引的数据访问模式。文章通过示例代码展示了如何定义及使用这两种特性,并提供了常见问题及其解决方案,帮助读者写出更健壮、易维护的代码。希望读者能从中学习到如何有效利用属性和索引器增强C#类的功能性。
92 12
|
6月前
|
存储 编译器 C#
|
3月前
|
存储 安全 编译器
C#中的属性
C#中的属性
45 7
|
5月前
|
开发框架 .NET 编译器
程序与技术分享:C#基础知识梳理系列三:C#类成员:常量、字段、属性
程序与技术分享:C#基础知识梳理系列三:C#类成员:常量、字段、属性
37 2
|
4月前
|
C#
C#中使用IntPtr.Size属性来判断当前系统是32位还是64位
这段代码首先检查 `IntPtr.Size`的值,如果是4,则输出"当前系统是32位";如果是8,则输出"当前系统是64位";如果都不是,就输出"未知系统位数"。
59 0
|
6月前
|
存储 JSON C#
C# 通过阿里云接口实现人脸属性识别
C# 通过阿里云接口实现人脸属性识别
|
6月前
|
Java C#
C#学习相关系列之多线程(七)---Task的相关属性用法
C#学习相关系列之多线程(七)---Task的相关属性用法
|
6月前
|
C#
C# Dev TreeList常用属性方法
C# Dev TreeList常用属性方法