C#:反射和特性
一、反射概念与Type类
1、程序在运行过程中,可以查看其他程序集或本身程序集中的元数据的行为叫做反射。
程序集:项目中所有代码以及嵌入式资源的集合。
元数据:我们编写的程序以及程序内数据。
2、反射的作用:
通过反射可以读取程序集(.dll、.exe)中代码内容
可以根据字符串类名,来动态创建类的对象
可以动态获取对象中的信息(方法、属性、字段)
可以根据字符串方法名称来调用执行
3、反射的常用类
1) Type类:设计用来包含类型的特性,可以获取程序使用的类型的信息。(可以获得一个类包含的成 员与方法。)
2)命名空间 using System.Reflection;
-
//实体人员类
-
public class Person{
-
public string Name;
-
public int Age;
-
private int _ID;
-
-
//属性
-
public int ID{
-
get{return _ID;}
-
set{_ID=value;}
-
}
-
-
public DisplayID(){
-
Console.WriteLine(_ID);
-
}
-
-
public DisplayName(){
-
Console.WriteLine(Name);
-
}
-
-
public DisplayAge(){
-
Console.WriteLine(Age);
-
}
-
}
-
-
-
using System.Threading.Tasks; //反射的命名空间
-
class Demo(){
-
public void Test1(){
-
Person per =new Person();
-
Type tyPersonObj=per.GetType(); //反射定义
-
-
//显示类的名称
-
Console.WriteLine(tyPersonObj.Name);
-
//显示类所属的命名空间
-
Console.WriteLine(tyPersonObj.Namespace);
-
//显示类所属的程序集
-
Console.WriteLine(tyPersonObj.Assembly);
-
//获取类是否为公共、密封、私有
-
Console.WriteLine(tyPersonObj.IsPublic);//True
-
Console.WriteLine(tyPersonObj.IsSealed);//False
-
Console.WriteLine(tyPersonObj.IsPrimitive);//False
-
//获取字段GetFields()方法
-
FieldInfo[] ingoArray=tyPersonObj.GetFields();
-
Foreach(FieldInfo item in ingoArray){
-
Console.WriteLine(item.Name);
-
}
-
//获取属性GetProperties()方法
-
PropertyInfo[] propArray=tyPersonObj.GetProperties();
-
Foreach(PropertyInfo item in propArray){
-
Console.WriteLine(item.Name);
-
}
-
//获取方法GetMethods()方法
-
MethodInfo[] metgodArray=tyPersonObj.GetMethods();
-
Foreach(MethodInfo item in metgodArray){
-
Console.WriteLine(item.Name);
-
}
-
}
-
static void Main(string[] args){
-
Demo obj=new Demo();
-
obj.Test1();
-
}
-
}
二、程序集Assembly与动态调用
1) Assembly类:得到一个程序集中的反射信息
2)使用反射技术,来动态调用
缺点:运行速度慢
优点:可以使得类对象之间的调用关系在“运行期”进行低耦合调用,可以随着配置文件的改变进行改变。
3)程序集中的两种存在方式
*.dll形式存在的程序集(不能直接运行,是“类库”)
*.exe的程序集,可以点击直接运行
如何加载程序集:
Assembly.Load();//不推荐使用
Assembly.LoadFrom(“程序集的完整路径名称”);
-
//学习Assembly程序集
-
using System.Reflection;
-
class Demo{
-
public void Test1(){
-
//通过路径直接得到程序集的对象
-
Assembly assObj=Assembly.LoadFrom(@"E:\System.dll");
-
//通过程序及,得到程序集中所有的类
-
Type[] typArray=assObj.GetTypes();
-
foreach(Type item in typArray){
-
Console.WriteLine(item.Name);
-
}
-
//根据类名与方法名(字符串),动态调用
-
Type type=assObj.GetType("类名字符串");//包含命名空间的类名
-
//根据type创建对象
-
Object obj=Activator.CreateInstance(type);//动态调用类的无参构造方法
-
//获得方法信息
-
//Type[] typeArrayWuthPara={type(int)};//重载有参数确定方法重载中有参数
-
MethodInfo method=type.GetMethod("方法名称字符串");//如果需要重载,则需要在后面添加一个新 //的参数new Type[0],表示重载无参,重 //载有参则调用新定义的Type数组名 //typeArrayWuthPara
-
//调用有参时添加的语句
-
//object[] objArray=new object[1];
-
//object[0]=参数;
-
//调用方法
-
method.Invoke(obj,null);//null表示没有参数,如果调用有参方法,null需要换成object数组名
-
}
-
static void Main(string[] args){
-
Demo obj=new Dmeo();
-
Obj.Test1();
-
}
-
}
反射调用私有方法与属性
-
class Person{
-
private int _ID;
-
//属性
-
public int ID{
-
get{return _ID;}
-
set{_ID=value;}
-
}
-
public void DisplayPrivate(){
-
Console.WriteLine("person类,私有方法,一般情况不可能调用");
-
}
-
}
-
-
using System.Reflection;
-
class Demo{
-
//调用私有方法
-
public void Test1(){
-
string strClassName="Person";
-
string strMethodName="DisplayPrivate";
-
Assembly assObj=Assembly.LoadFrom(strClassName);
-
//根据类名与方法名(字符串),动态调用
-
Type type=assObj.GetType("类名字符串");//包含命名空间的类名
-
//根据type创建对象
-
Object obj=Activator.CreateInstance(type);//动态调用类的无参构造方法
-
MethodInfo method=
-
type.GetMethod("strMethodName",BindingFlags.NonPublic|BindingFlags.Instance);
-
method.Invoke(obj,null);
-
}
-
//调用属性
-
public void Test2(){
-
string strClassName="Person";//类的名称
-
string strPropertydName="ID";//属性的名称
-
Assembly assObj=Assembly.LoadFrom(strClassName);
-
//根据类名与方法名(字符串),动态调用
-
Type type=assObj.GetType("类名字符串");//包含命名空间的类名
-
//根据type创建对象
-
Object obj=Activator.CreateInstance(type);//动态调用类的无参构造方法
-
//获得属性
-
PropertyInfo prop=type.Getproperty(strPropertydName);
-
//设置属性
-
prop.SetValue(obj,100);
-
//得到属性值
-
string result=prop.GetValue(obj,null).ToString();
-
Console.WriteLine(result);
-
}
-
static void Main(string[] args){
-
Demo obj=new Dmeo();
-
Obj.Test1();
-
Obj.Test2();
-
}
-
}
三、Type深入方法
bool IsAssignableFrom(Type c) //用来判断一个类或接口是否另一个类的父类或接口
bool IsInstanceOfType(object o)//判读对象o 是否是当前类(或者子类)的实例,或者实现本接口
bool IsSubclassOf(Type c)//判断当前类是否为类c (参数)的子类
-
//父类
-
public class Men{}
-
//子类
-
public class ZhangSan:Men,ICanSpeak{}
-
//普通类 无继承
-
public class Dog{}
-
//接口
-
interface ICanSpeak{}
-
//学习Type更多的方法
-
//1.判断一个类是否为(参数)类的父类或者接口
-
//
-
//
-
//
-
using System.Reflection;
-
class Demo{
-
//bool IsAssignableFrom(Type c) //用来判断一个类或接口是否另一个类的父类或接口
-
public void Test1(){
-
Type typeMen=typeof(Men);
-
Type typeZhangSan=typeof(ZhangSan);
-
Type typeDog=typeof(Dog);
-
Type typeICanSpeak==typeof(ICanSpeak);
-
//判断Men是ZhangSan的父类吗
-
Console.WriteLine(typeMen.IsAssignableFrom(typeZhangSan));//true
-
//判断Men是Dog的父类吗
-
Console.WriteLine(typeMen.IsAssignableFrom(typeDog));//False
-
//判断ICanSpeak是否为ZhangSan的接口
-
Console.WriteLine(typeICanSpeak.IsAssignableFrom(typeZhangSan));//true
-
//判断ICanSpeak是否为Dog的接口
-
Console.WriteLine(typeICanSpeak.IsAssignableFrom(Dog));//false
-
}
-
//bool IsInstanceOfType(object o)//判读对象o 是否是当前类(或者子类)的实例,或者实现本接口
-
public void Test2(){
-
Type typeMen=typeof(Men);
-
Type typeICanSpeak==typeof(ICanSpeak);
-
Men MenObj=new Men();
-
ZhangSan zhangsanObj=new ZhangSan();
-
Dog dogObj=new Dog();
-
//typeMen是MenObj的实例吗?
-
Console.WriteLine(typeMen.IsInstanceOfType(MenObj));//T
-
Console.WriteLine(typeMen.IsInstanceOfType(zhangsanObj));//T
-
Console.WriteLine(typeMen.IsInstanceOfType(dogObj));//F
-
Console.WriteLine(typeICanSpeak.IsInstanceOfType(zhangsanObj));//T
-
Console.WriteLine(typeICanSpeak.IsInstanceOfType(MenObj));//F
-
}
-
//bool IsSubclassOf(Type c)//判断当前类是否为类c (参数)的子类
-
public void Test3(){
-
Type typeMen=typeof(Men);
-
Type typeZhangSan=typeof(ZhangSan);
-
Type typeDog=typeof(Dog);
-
Console.WriteLine(typeZhangSan.IsSubclassOf(typeMen)); //T
-
Console.WriteLine(typeDog.IsSubclassOf(typeMen));//F
-
}
-
static void Main(string[] args){
-
Demo obj=new Demo();
-
obj.Test1();
-
obj.Test2();
-
obj.Test3();
-
}
-
}
四、预定义特性Attribute
1.特性(Attribute)是一种允许我们向程序集增加元数据的语言结构,提供了一种将声明性信息与代码关联起来的途径。
2.Obsolete特性将过时的方法与类标注为“过时”(过期)的,且在编译时,显示警告信息。
3.Conditional特性一般用于程序开发过程中的“测试方法”的编写。测试阶段定义“测试的宏”,发布商业版本,则取消宏即可。
-
/*
-
学习特性
-
一:系统特性
-
1:Obsolete特性(即:过时特性)
-
2:Conditional特性
-
3:Serializable 声明结构可以被序列化
-
4:NonSerialized 声明结构不可以被序列化
-
5:DLLImport 声明是非托管代码实现的
-
二、自定义特性
-
三、条件编译
-
1.特性Conditional 适用条件:针对方法
-
2.使用"预编译”指令 #if debug
-
表达式
-
#else
-
表达式
-
#endif
-
*/
-
-
-
using System;
-
using System.Collections.Generic;
-
using System.Linq;
-
using System.Text;
-
using System.Therading.Tasks;
-
using System.Reflection;//反射的命名空间
-
using System.Diagnostics;//Conditional特性的命名空间,Obsolete不受影响
-
namespace 学习特性{
-
class Demo1{
-
-
//学习Obsolete如果加参数True,旧方法不可用,会引发错误,不加则默认false仅提醒自定义的字符串
-
[]
-
public void OldMethod(){
-
Console.WriteLine("这是旧的方法");
-
}
-
public void NewMethod(){
-
Console.WriteLine("这是新的方法");
-
}
-
public void Test1(){
-
//OldMethod();
-
NewMethod();
-
}
-
-
//学习Conditional ,条件执行,默认不执行
-
[]
-
public void TestMethod(){
-
Console.WriteLine("这是测试方法");
-
}
-
public void Method1(){
-
Console.WriteLine("这是方法1");
-
}
-
public void Method2(){
-
Console.WriteLine("这是方法2");
-
}
-
//条件编译
-
public void Test3(){
-
Console.WriteLine("这是条件编译");
-
Console.WriteLine("aaa");
-
-
Console.WriteLine("bbb");
-
-
Console.WriteLine("ccc");
-
-
Console.WriteLine("ddd");
-
}
-
public void Test2(){
-
TestMethod();
-
Method2;
-
TestMethod();
-
Method1;
-
TestMethod();
-
Method1;
-
Method2;
-
Method1;
-
}
-
static void Main(string[] args){
-
Demo1 obj=new Demo1();
-
obj.Test1();
-
obj.Test2();
-
obj.Test3();
-
}
-
}
-
}
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhggbbig
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01