C#语言笔记12

本文探讨了C#编程中的关键特性:反射如何访问类信息,Obsolete用于标记过时方法,Conditional控制方法启用条件,以及CallerInfo提供调用者上下文。通过实例了解这些特性如何增强代码灵活性和管理

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

反射和特性

 

一个类中的数据是存储在对象中的,但是Type对象只存储类的成员

PropertyInfo用于存储一个属性的信息

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
namespace learn
{
    class ProgramClass
    {
        private int id;
        private string name;
        public int num;
        public string Name { get; set; }
        public int Number { set; get; }
        public string Address { set; get; }
        public void Test1()
        {

        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //每一个类对应一个type对象
            ProgramClass Myclass = new ProgramClass();
            Type type = Myclass.GetType();

            Console.WriteLine("获取类名:\t" + type.Name);
            Console.WriteLine("获取所在的命名空间:\t" + type.Namespace);
            Console.WriteLine("获取类所在的程序集:\t" + type.Assembly);

            Console.WriteLine();

            //FieldInfo访问类的信息
            FieldInfo[] arr = type.GetFields();//FieldInfo需要包含System.Reflection;
            foreach (FieldInfo r in arr)
            {
                Console.WriteLine(r.Name); //只能获取公共成员的属性
            }

            Console.WriteLine();

            //PropertyInfo访问属性的信息
            PropertyInfo[] prores = type.GetProperties();
            foreach (var r in prores)
            {
                Console.WriteLine(r.Name);
            }

            Console.WriteLine();

            //MethodInfo访问方法的信息
            MethodInfo[] arr3 = type.GetMethods();
            foreach (var r in arr3)
            {
                Console.WriteLine(r.Name);
            }//除去自定义方法外,还存在GetType,ToString,Equals,GetHashCode
             //get_Name
             //set_Name
             //get_Number
             //set_Number
             //get_Address
             //set_Address
             //上面是属性里的get和set方法
             //Test1
             //GetType
             //ToString
             //Equals
             //GetHashCode
        }
    }
}

 Obsolete特性

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace learn
{
    class Obsolete
    {
        static void Main(string[] args)
        {
            Old();//这里会提示这个方法过时了
            //Old1();这里会发现无法使用
        }

        [Obsolete("你正在使用旧方法")]//用于表示方法被弃用了
        static void Old()
        {
            Console.WriteLine("Old");
        }

        [Obsolete("", true)]//true代表这个方法无法被使用
        //[Obsolete(true)]这样写是无效的

        static void Old1()
        {

        }
        static void New()
        {
            Console.WriteLine("New");
        }
    }

}

Conditional特性

#define Test1
//在这里定义Test1
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace learn
{
    class Conditiona
    {
        static void Main(string[] args)
        {
            Test1();
            Test2();
            Test1();

            //如果我们想取消test1的使用,如果使用注释过于麻烦Obsolete特性只会让代码报错

        }
        [Conditional("Test1")]//需要using System.Diagnostics;
        //这里的Test1必须使用define定义后,Test1方法才能使用
        static void Test1()
        {
            Console.WriteLine(1);
        }
        static void Test2()
        {
            Console.WriteLine(2);
        }
    }
}

调用者信息特性

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace learn
{
    class Pro
    {

        static void Print(string str, [CallerFilePath] string fileName = "", [CallerLineNumber] int lineNumber = 0, [CallerMemberName] string methodName = "")
        //fileName lineNumber methodName让系统帮我传递
        {
            Console.WriteLine(str);
            Console.WriteLine(fileName);//调用方法的文件位置
            Console.WriteLine(lineNumber);//调用方法的代码行数
            Console.WriteLine(methodName);//调用方法的方法名称
        }
        static void Main(string[] args)
        {
            Print("Hello World");
        }
    }
}

DebuggerStepThrough特性

 要小心使用该特性,不要排除了可能出现bug的代码

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace learn
{
    class DebuggerStepThrough
    {
        [DebuggerStepThrough]//debug调试时会跳过调试该方法
        static void Print(string str, [CallerFilePath] string fileName = "", [CallerLineNumber] int lineNumber = 0, [CallerMemberName] string methodName = "")
        //fileName lineNumber methodName让系统帮我传递
        {
            Console.WriteLine(str);
            Console.WriteLine(fileName);//调用方法的文件位置
            Console.WriteLine(lineNumber);//调用方法的代码行数
            Console.WriteLine(methodName);//调用方法的方法名称
        }
        static void Main(string[] args)
        {
            Console.WriteLine("1");
            Print("Hello World");
            Console.WriteLine("11");
        }
    }
}

特性是一种允许我们向程序的程序集增加元数据的语言结构。
它是用于保存程序结构信息的某种特殊类型的类

创建自定义特性

[AttributeUsage(AttributeTargets.Class)]

这里AttributeTargets是一个枚举类型

 编写特性类的名称时,需要在定义的名称后加上Attribute,比如名称为My,则为MyAttribute

特性类需要继承System.Attribute

一般情况下需要sealed对该类进行密封

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值