C#笔记之二 特性与反射

本文介绍了编程中特性的作用,包括内置特性如过时提醒、序列化标志和条件编译,自定义特性的创建与使用,以及反射如何在运行时访问和处理这些特性。还讨论了默认值特性和反射的用途,如查看和输出元数据。
摘要由CSDN通过智能技术生成

特性的定义

特性(Attributes)是一种声明性标记,用于向程序实体(如类、方法、属性等)添加元数据。特性提供了一种在源代码中嵌入元数据的方法,这些元数据可以在运行时通过反射来访问。

简单来说就是相当于标注附加数据。

特性的种类

内置特性

一系列用于按照对应用法使用的系统给出的特性。

过时提醒:

[Obsolete]: 标记一个程序实体为过时的,编译器会发出警告。

[Obsolete("This method is obsolete. Use NewMethod instead.")]
public void OldMethod() { /* ... */ }

 它的定义和使用:

[Obsolete(
   message
)]
[Obsolete(
   message,
   iserror
)]

  1. 参数 message,是一个字符串,描述项目为什么过时以及该替代使用什么。
  2. 参数 iserror,是一个布尔值。如果该值为 true,编译器应把该项目的使用当作一个错误。默认值是 false(编译器生成一个警告)。

序列化提醒 :

[Serializable]: 表示一个类可以被序列化。

[Serializable]
public class SerializableClass { /* ... */ }

它的使用:

using System;

[Serializable]
public class MyClass
{
    public int Id { get; set; }
    public string Name { get; set; }

    public MyClass(int id, string name)
    {
        Id = id;
        Name = name;
    }
}

 在上述示例中,MyClass 类被标记为可序列化,这意味着该类的对象可以被序列化和反序列化。通常情况下,如果你想要将一个类的对象序列化(例如保存到文件或通过网络发送),你需要确保该类及其所有嵌套对象都是可序列化的,否则会抛出序列化异常。

指定条件编译提醒:

 [Conditional]: 用于指定条件编译。

[Conditional("DEBUG")]
public void DebugMethod() { /* ... */ }
 条件编译特性的使用:
#define DEBUG
using System;
using System.Diagnostics;
public class Myclass
{
    [Conditional("DEBUG")]
    public static void Message(string msg)
    {
        Console.WriteLine(msg);
    }
}
class Test
{
    static void function1()
    {
        Myclass.Message("In Function 1.");
        function2();
    }
    static void function2()
    {
        Myclass.Message("In Function 2.");
    }
    public static void Main()
    {
        Myclass.Message("In Main function.");
        function1();
        Console.ReadKey();
    }
}

 自定义特性

自定义特性的创建

自己定一个特性由于给你想标注的实体:类或者方法。

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public class MyCustomAttribute : Attribute
{
    public string Description { get; set; }

    public MyCustomAttribute(string description)
    {
        Description = description;
    }
}
  • [AttributeUsage(...)]: 这是 AttributeUsageAttribute 的应用,它是用来指定自定义特性的使用方式的特性。

  • AttributeTargets.Class | AttributeTargets.Method: 指定可以应用该特性的程序实体类型。在这里,它表示该特性可以应用到类和方法上。

  • AllowMultiple = true: 指定是否允许在同一个程序实体上多次应用该特性。在这里,AllowMultiple = true 表示允许在同一个类或方法上多次应用 MyCustomAttribute

这样定义后,你就可以在类和方法上使用 MyCustomAttribute,并且可以多次在同一个类或方法上应用它,因为 AllowMultiple 设置为 true

 自定义特性的使用

[MyCustom("Description 1")]
[MyCustom("Description 2")]
public class MyClass
{
    [MyCustom("Method 1")]
    [MyCustom("Method 2")]
    public void MyMethod() { /* ... */ }
}

属性的特性

应用于属性而非普通方法和类的特性。

默认取值特性

用于给出属性的默认值。

public class MyClass
{
    [DefaultValue(42)]
    public int MyProperty { get; set; }
}

反射的定义

个人理解:指程序可以访问、检测和修改它本身状态或行为的一种能力。

反射的用处

反射(Reflection)有下列用途:

  • 它允许在运行时查看特性(attribute)信息。
  • 它允许审查集合中的各种类型,以及实例化这些类型。
  • 它允许延迟绑定的方法和属性(property)。
  • 它允许在运行时创建新类型,然后使用这些类型执行一些任务。

反射的使用

查看元数据

using System;

[AttributeUsage(AttributeTargets.All)]
public class HelpAttribute : System.Attribute
{
   public readonly string Url;

   public string Topic  // Topic 是一个命名(named)参数
   {
      get
      {
         return topic;
      }
      set
      {

         topic = value;
      }
   }

   public HelpAttribute(string url)  // url 是一个定位(positional)参数
   {
      this.Url = url;
   }

   private string topic;
}
[HelpAttribute("Information on the class MyClass")]
class MyClass
{
}

namespace AttributeAppl
{
   class Program
   {
      static void Main(string[] args)
      {
         System.Reflection.MemberInfo info = typeof(MyClass);
         object[] attributes = info.GetCustomAttributes(true);
         for (int i = 0; i < attributes.Length; i++)
         {
            System.Console.WriteLine(attributes[i]);
         }
         Console.ReadKey();

      }
   }
}

这段代码演示了使用我们新建的自定义特性修饰myclass之后使用反射提取特性的类别。

输出元数据:

 HelpAttribute helpinfo = (HelpAttribute)attributes[i];
 if (null != helpinfo)
 {
     System.Console.WriteLine("Url: " + helpinfo.Url);
     System.Console.WriteLine("Topic: " + helpinfo.Topic);
 }   

 注意看图如果不使用类型转换是没法直接输出Url的。

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值