反射和特性
一个类中的数据是存储在对象中的,但是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对该类进行密封