《随笔二十五》——C#中的 “ 反射和特性 ”

本文详细探讨了C#中的反射和特性,包括如何通过GetType和typeof获取Type对象,特性的作用、类型以及使用,如Obsolete、Conditional、CallerInfo等特性,并介绍了如何声明和使用自定义特性,以及如何访问和应用特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

Type 类

使用 GetType方法 或使用typeof运算符 来 获取 Type 对象 (482P)

什么是特性

在程序集中使用C# 中已定义的特性 (485P)

使用 Obsolete 特性 来标识某段代码是已过时的(485P)

使用 Conditional 特性 来禁止某些方法被调用(486P)

使用 CallerFilePath, CallerLineNumber, CallerMemberName 特性 来访问文件路径、代码行数、调用成员名称 (488P)

使用 DebuggerStepThrough 特性 (489P)

.NET中定义的重要特性列表 (490P)

为一个程序结构应用多个特性 (490P)

将特性作用于 类的 字段、属性上 (490P)

显式地标记特性,然后应用到特定的目标程序结构上 (491P)

C# 语言定义的10个标准的特性目标列表(491P)

使用assembly 和 mode 名称来设置全局特性 (491P)

声明自定义特性 (492P)

特性的构造函数 (492P)

给特性的构造函数使用位置参数和命名参数 (493P)

使用 AttributeUsage 预定义特性应用到自定义特性上 (494P)

使用 IsDefined 方法 来访问特性(496P)

使用 GetCustomAttributes 方法 来访问特性(496P)


  • 有关程序及其类的数据称为元数据,并存储在程序集中。
  • 程序可以在运行时查看其他程序集或其自身的元数据。当一个正在运行的程序查其自身的元数据 或者 其他程序的元数据时,它被称为反射。
  • 要使用反射,必须使用 System.Reflection 命名空间

Type 类


C#中的类型,比如系统预定义的类型, BCL 中的类型,自定义的类型。 每一种类型都有其自身的成员和 特性。

BCL声明了一个名为Type的抽象类,它被设计为包含类型的特性。 使用Type类的对象可以获取有关程序正在使用的类型的信息。

Type 类需要注意的有:

  • 对于程序中使用的每一种类型,CLR都会创建一个Type类的类型对象,其中包含关于该类型的信息。
  • 程序中使用的每种类型都与单独的Type对象相关联
  • 无论创建了多少个类型实例,只有一个 Type 对象与所有实例相关联。

下图显示了一个运行中的程序,其中有两个MyClass对象和一个OtherClass对象。注意,尽管MyClass有两个实例,但是只有一个Type对象表示它。

CLR为程序中使用的每种类型实例化Type类型的对象。

可以从Type对象中获得关于类型的几乎所有信息。 下标列出了 System.Type类部分成员

点击这里进入官网,了解更多的成员信息 


使用 GetType方法 或使用typeof运算符 来 获取 Type 对象 (482P)


可以使用 GetType方法 或使用typeof运算符 来获取 Type对象。 Type对象包含一个名为 GetType 的方法,该方法返回对实例的Type对象的引用。 由于每个类型最终都是从 object 派生的,因此可以在任何类型的对象上调用GetType方法来获取其Type对象。

namespace HelloWorld_Console
{
    class BaseClass
    {
        public int BaseField = 0;
    }
    class DerivedClass:BaseClass
    {
        public int DerivedField = 0;
    }
    class Program
    {
        static void Main()
        {
            var bc = new BaseClass();
            var dc = new DerivedClass();

            BaseClass[] bca = new BaseClass[] { bc, dc };
            foreach(var v in bca)
            {
                Type t = v.GetType(); // 获取类型
                WriteLine($"Object type: {t.Name}"); 
               
                FieldInfo[] fi = t.GetFields();  // 获取字段信息
                foreach (var f in fi)
                {
                    WriteLine($"      Field: {f.Name}");
                }
                WriteLine();
            }
        }
    }
}

您还可以使用 typeo f运算符来获取 Type 对象。 只需提供类型的名称作为操作数,它就会返回对Type对象的引用,如下所示:

namespace HelloWorld_Console
{
    class BaseClass
    {
        public int BaseField = 0;
    }
    class DerivedClass:BaseClass
    {
        public int DerivedField = 0;
    }
    class Program
    {
        static void Main()
        {
            Type tbc = typeof(DerivedClass); // Get the type.
            Console.WriteLine("Result is {0}.", tbc.Name);
            Console.WriteLine("It has the following fields:"); // Use the type.
            FieldInfo[] fi = tbc.GetFields();
            foreach (var f in fi)
                Console.WriteLine(" {0}", f.Name);
        }
        
    }
}

什么是特性


特性是一种语言结构,允许您将元数据添加到程序集中。 它是一种特殊类型的类,用于存储有关程序结构的信息。

  • 应用特性的程序结构称为其目标
  • 设计用来获取和使用元数据的程序,如对象浏览器,被称为特性的消费者。
  • .Net 中预定义了一些特性,您还可以声明自定义特性

下图给出了使用特性所涉及的组件的概述,并说明了关于它们的以下几点:

  • 我们在源代码中将特性应用于程序结构。
  • 编译器获取源代码并且从特性产生元数据, 然后把元数据放到程序集中。
  • 消费者程序可以访问属性的元数据以及程序其余组
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值