[C#复习向整合]特性

目录

一.特性概念

二.自定义特性

三.特性的使用

四.限制自定义特性的使用范围

五.系统自带特性

六.系统自带特性 - 调用者信息特性

七.系统自带特性 - 条件编译特性

八.系统自带特性 - 外部dll包函数特性


一.特性概念

特性是一种允许我们向程序的程序集添加元数据的语言结构.

是用于保存程序结构信息的某种特殊类型的类.

特性提供功能强大的方法以将声明信息与C#代码(类型,方法,属性等)相关联.

特性与程序实体关联后,即可在运行时使用反射查询特性信息.

特性的目的是告诉编译器把程序结构的某族元数据嵌入程序集中.

它可以放置在几乎所有的声明中(类,变量,函数等等声明).

概括:

特性本质是个类.

我们可以利用特性类为元数据添加额外信息.

之后可以通过反射来获取这些额外信息.

二.自定义特性

继承特性基类 Attribute

//自定义特性的命名,通常后面加上Attribute
class MyCustomAttribute : Attribute
{
    public string info;
    public MyCustomAttribute(string info)
    {
        this.info = info;
    }
}

三.特性的使用

基本语法: [特性名(参数列表)]

本质上就是在调用特性类的构造函数.

写在类,函数,变量上一行,表示它们具有该特性信息.

(接上一段代码)

[MyCustom("test")]
class MyClass
{
    [MyCustom("一个函数")]
    private int value;
    [MyCustom("一个函数")]
    public void TestFunc()
    {

    }
    public void TestFunc([MyCustom("一个参数")] float f)
    {

    }
}
static void Main(string[] args)
{
    MyClass mc = new MyClass();
    Type t = mc.GetType();
    //t = typeof(MyClass);
    //t = Type.GetType("特性.MyClass");

    //判断是否使用某种特性
    //第一个参数填特性类,第二个参数表示是否查找其继承类是否使用了特性
    //属性和事件忽略第二个参数
    if(t.IsDefined(typeof(MyCustomAttribute),false))
    {
        //该方法只能判断MyClass类是否使用了该特性
        //类里面的成员是否使用是判断不了的
        Console.WriteLine("使用特性MyCustomAttribute");
    }

    //用反射来获取特性的额外信息
    //参数表示是否查找继承类
    //获取元数据所有特性
    object[] array = t.GetCustomAttributes(true);
    for(int i = 0;i< array.Length;i++)
    {
        if(array[i] is MyCustomAttribute)
        {
            Console.WriteLine((array[i] as MyCustomAttribute).info);
        }
    }
}

四.限制自定义特性的使用范围

为特性类再加上特性,就能限制其使用范围.

//参数一: 使用地方,这里表示类或结构体,用位或| 连接
//参数二: 使用允许多个特性实例用在同一个目标上(若为true,则一个目标可以重复加一样的特性)
//参数三: 特性是否能被派生类和重写成员继承,若否,则派生类不会有父类的一些特性
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true, Inherited = true)]
class MyCustom2Attribute : Attribute
{

}

五.系统自带特性

过时特性Obsolete.提示用户使用的成员已经过时,建议使用新的方法

class TestClass
{
    //参数一: 调用方法时,提示的内容
    //参数二: true-使用方法时报错,false-使用方法时警告
    [Obsolete("该方法已过时",false)]
    public void OldFunc()
    {

    }
    public void NewFunc()
    {

    }
}

六.系统自带特性 - 调用者信息特性

获得是哪个文件调用: CallerFilePath

获得是哪一行调用: CallerLineNumber

获得是哪个函数调用: CallerMemberName

需要命名空间 System.Runtime.CompilerServices

public void TestFunc([CallerFilePath]string str = "")
{
    Console.WriteLine(str);
    //调用时,会输出调用的文件
    //该特性自动为str赋了文件路径的默认值
    //可以配合异常捕获来打印错误信息
}

七.系统自带特性 - 条件编译特性

条件编译特性: Conditional

配合#define使用

需要命名空间System.Diagnostics

主要用在一些有时想执行,有时不想执行的代码上

#define FUNC

[Conditional("FUNC")]
public void Func()
{    
    //该函数只有在FUNC被预处理定义了才会有用
    //没有预处理,即使写了调用的位置,也不会调用
    //没有预处理就没有编译它
}

static void Main(string[] args)
{
    Func();
}

八.系统自带特性 - 外部dll包函数特性

DllImport

需要命名空间System.Runtime.InteropServices

用来标记非.Net(C#)的函数,表明该函数在一个外部dll中定义

一般用来调用C或C++的dll包

//[DllImport("dll包文件名或路径")]
[DllImport("Test.dll")]
public static extern void Function(int a);
//注意,必须要加static extern
//函数的参数返回值要和dll对应函数匹配
//相当与把dll函数映射到c#内

资料来源<唐老狮C#教程>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值