C# 反射机制与艺术

 

目录:

一. 反射的关键特色

  1.照中一个坏关键之连串就是
Type

    1)当没有目的的时候使用这种方法来取得有项目标Type

    2)当曾得到对象后经对象的GetType()方法来博取指定对象的种的Type对象

**  2.得到Person类中之装有的点子**

**  3.获取有项目标有属性**

**  4.获取类中之拥有字段,私有字段无法获取**

**  5.取具有成员,不分包个人成员**

**二. 反射动态加载程序集**

**  1.动态加载一个序集**

**  2.沾刚刚加载的程序集中之持有的类**

**    1)GetTypes()获取了所有的型**

**    2)只获这些public的连串**

**  3.收获程序集中某个类的Type**

**  4.动态调用类的方**

**    1)调用无参数无重回值的道**

**    2)
调用带参数,带再次来到值的艺术**

**      1>
调用无带来重载的形式**

**      2>调用带重载的法子**

**  5.
经反射获取类的性质,并赋值**

**    1)获取Name属性**

    2)为性赋值

    3) 获取属性值

    4)获取情势并调用

  6.手动查找类型的构造函数,并且调用该构造函数来创建项目标目的

**三.
其他的反射中之有些措施**

**  1. bool IsAssignableFrom(Type
c) 判断时底路的变量是休是能够承受c类型变量的赋值**

**  2. bool
IsInstanceOfType(object
o):判断对象o是否是当下仿佛的实例(当前相仿但是o的好像、父类、接口)**

**  3. bool IsSubclassOf(Type
c):判断当前看似是否是类c的子类**

**  4. IsAbstract
判定是否为架空的,含接口**

**————————————————————————————————————————————————————————————————————————————**

 

映是什么?

映:通过动态获取程序集,并拿走其中的档次元数据,然后访问该种的进程。

一. 反射的重点特色

每当介绍反射的根本特色往日大家事先修建一个Person类(上边都是本着Person类举办操作)

C# 1C# 2

    class Person
    {

        public int _height;

        public string Name { get; set; }
        public int Age { get; set; }
        public string Email { get; set; }

        public void Say()
        {
            Console.WriteLine("Hello everyone!");
        }


        public void SayMorning()
        {
            Console.WriteLine("Good morning everybody!");
        }

        //私有的
        void Do()
        {
            Console.WriteLine("Just do it!");
        }
    }

View Code

1.反光中一个挺关键的色就是
Type

拿到Person类型的Type对象(Type对象中不怕是存放了片有关某个项目标装有音讯的内容。[某某项目标Type对象就是该项目“类型元数据”])

抱Type对象来有限种植办法:


1)当没有目标的时利用这种办法来收获有项目标Type

Type type = typeof(Person);

2)当都获对象后透过对象的GetType()方法来取得指定对象的路的Type对象
Person p = new Person();
Type personType = p.GetType();

2.落Person类中之兼具的不二法门

(通过Type对象的GetMethods()能够得到指定项目标所有的点子中包括编译器自动生成的点子与由父类中持续来之主意,但是未包含private方法)
MethodInfo[] methods = personType.GetMethods();
for (int i = 0; i < methods.Length; i++)
{
Console.WriteLine(methods[i].Name);
}

 

3.得有项目标备属性
PropertyInfo[] properties = personType.GetProperties();
for (int i = 0; i < properties.Length; i++)
{
Console.WriteLine(properties[i].Name);
}
Console.ReadKey();

4.获取类中的有所字段,私有字段无法拿到
FieldInfo[] fields = personType.GetFields();
for (int i = 0; i < fields.Length; i++)
{
Console.WriteLine(fields[i].Name);
}
Console.ReadKey();

5.博有成员,不带有个人成员
MemberInfo[] members = personType.GetMembers();
for (int i = 0; i < members.Length; i++)
{
Console.WriteLine(members[i].Name);
}
Console.ReadKey();

二. 反射动态加载程序集

于接收发射动态加载程序集,先将程序级的代码贴出(下面依旧本着先后集TestDll.dll进行操作)

C# 3C# 4

namespace TestDll
{
    public class Class1
    {
    }

    class MyClass
    {
        public void English()
        {
            Console.WriteLine("Hi,English");
        }
    }

    public abstract class MyAbstractClass
    {

    }

    public static class MyStaticClass
    {
    }


    public class Person
    {
        public Person()
        {

        }

        public Person(string name, int age, string email)
        {
            this.Name = name;
            this.Age = age;
            this.Email = email;
        }

        public string Name { get; set; }
        public int Age { get; set; }
        public string Email { get; set; }

        public void GetNameValue()
        {
            Console.WriteLine(this.Name + "--" + this.Age + "--" + this.Email);
        }


        public void English()
        {
            Console.WriteLine("Hi,English");
        }

        public void China()
        {
            Console.WriteLine("你好,中国");
        }

        public int Add(int n1, int n2)
        {
            return n1 + n2;
        }

        public int Add(int n1, int n2, int n3)
        {
            return n1 + n2 + n3;
        }
    }

    public class Student : Person, IFlyable
    {
        public string StudentNo { get; set; }

        #region IFlyable 成员

        public void Fly()
        {
            Console.WriteLine("I can Fly!");
        }

        #endregion
    }

    class Teacher : Person
    {

    }

    public delegate void MyDelegate();

    delegate void MyDelegate1();

    public enum GoodMan
    {
        高,
        富,
        帅
    }

    public interface IFlyable
    {
        void Fly();
    }
}

View Code

1.动态加载一个先后集
Assembly assembly = Assembly.LoadFile(@”D:\TestDll\bin\Debug\TestDll.dll”); 

专注:这么些地方是次与所在的绝地址 

2.获刚刚加载的次集中的装有的型
assembly.GetType() 等价于 typeof(Assembly)
1)GetTypes()获取了所有的体系
Type[] types = assembly.GetTypes();

2)只得到这些public的品类
Type[] types = assembly.GetExportedTypes();
for (int i = 0; i < types.Length; i++)
{
Console.WriteLine(types[i].Name);
}

3.取得程序集中某个类的Type
如:只获取Person类的Type
GetType()方法爆发重载,采取第二个重载,参数表示是若得到的色的“完全限定名称”,即:命名空间.类名
那里以到了Type,其实就是等价于typeof(Person)或者是:p.GetType();
Type personType = assembly.GetType(“_02TestDll.Person”);

赢得具有的不二法门:personType.GetMethods();

4.动态调用类的方法

(借用上边得到之Person类的办法)

抱有特定的主意(遵照办法名):personType.GetMethod(); 

1)调用无参数无重返值的方

MethodInfo method = personType.GetMethod(“SayHi”);
Console.WriteLine(method.Name);

//通过反射来创设一个Person类型的目的{其实就是是经过Person的Type来成立一个Person对象}

object objPerson = Activator.CreateInstance(personType);

//调用这多少个艺术
method.Invoke(objPerson, null);

2)
调用带参数,带重临值的方法

1> 调用无带来重载的办法
//找到相应之主意
MethodInfo method = personType.GetMethod(“Add”);
object obj = Activator.CreateInstance(personType);
//调用
object result = method.Invoke(obj, new object[] { 102, 203 });
Console.WriteLine(“调用Add方法的回值结果是:{0}”, result);
#endregion

2>调用带重载的计

//找到呼应的措施
MethodInfo method = personType.GetMethod(“Add”, new Type[] {
typeof(int), typeof(int), typeof(int) });
object obj = Activator.CreateInstance(personType);

//调用
int r = (int)method.Invoke(obj, new object[] { 1, 2, 3 });
Console.WriteLine(r);

5.
透过反射获取类的性,并赋值

(借用下边得到的Person类的点子)

1)获取Name属性
C#,PropertyInfo property = personType.GetProperty(“Name”);
object obj = Activator.CreateInstance(personType);
2)为性赋值
property.SetValue(obj, “张三”, null);

3) 获取属性值
string name = property.GetValue(obj, null).ToString();
Console.WriteLine(name);

 

4)获取情势并调用

MethodInfo method = personType.GetMethod(“GetNameValue”);
method.Invoke(obj, null);
Console.ReadKey();

6.手动查找类型的构造函数,并且调用该构造函数来成立项目标目的

翻看找到了相应的构造函数,不过还未曾调用
ConstructorInfo ctor = personType.GetConstructor(new Type[] {
typeof(string), typeof(int), typeof(string) });

起来调用构造函数
object obj = ctor.Invoke(new object[] { “hpp”, 16, “hpp@yahoo.com”
});
Console.WriteLine(obj.ToString());

MethodInfo method = personType.GetMethod(“GetNameValue”);
method.Invoke(obj, null);
Console.ReadKey();

三. 其他的反射中之一部分法

//动态加载一个主次集
Assembly assembly =
Assembly.LoadFile(@”D:\TestDll\bin\Debug\TestDll.dll”);

//获取类的Type
Type typePerson = assembly.GetType(“TestDll.Person”);

Type typeStudent = assembly.GetType(“TestDll.Student”);

Type typeIFlyable = assembly.GetType(“TestDll.IFlyable”);

1. bool IsAssignableFrom(Type c) 判断时的档次的变量是不是得承受c类型变量的赋值

//表示可以以Student类型赋值给Person类型,因为Student类型继承自Person类
bool b = typePerson.IsAssignableFrom(typeStudent); //true

//表示可以将Student类型赋值给IFlyable类型,因为Student类型继承自IFlyable接口

bool b = typeIFlyable.IsAssignableFrom(typeStudent);//true

//表示未得以拿Person类型赋值给IFlyable类型,因为Person类型没有继续IFlyable接口

bool b = typeIFlyable.IsAssignableFrom(typePerson);//false

2. bool IsInstanceOfType(object
o):判断对象o是否是眼前类似的实例(当前好像能够是o的好像、父类、接口)

//Person
object objPerson = Activator.CreateInstance(typePerson);
//Student
object objStudent = Activator.CreateInstance(typeStudent);

//当前接近就是Person类

bool b = typePerson.IsInstanceOfType(objPerson);//true

//Suntent类是Person类的子类

bool b = typePerson.IsInstanceOfType(objStudent);//true

//person类不是Student的子类

bool b = typeStudent.IsInstanceOfType(objPerson);//false

3. bool IsSubclassOf(Type
c):判断当前类似是否是类c的子类

//Person
object objPerson = Activator.CreateInstance(typePerson);
//Student
object objStudent = Activator.CreateInstance(typeStudent);

//Suntent类是Person类的子类

bool b = typeStudent.IsSubclassOf(typePerson);//true

//person类不是Student的子类

 bool b = typePerson.IsSubclassOf(typeStudent);//false

//这多少个再次回到是false,只验证类与类似里的父子类涉,接口不含。
bool b = typeStudent.IsSubclassOf(typeIFlyable);

4. IsAbstract
论断是否为架空的,含接口

Type typeMyAbsClass = assembly.GetType(“TestDll.MyAbstractClass”);
Type typeMyStaticClass = assembly.GetType(“TestDll.MyStaticClass”);

Console.WriteLine(typePerson.IsAbstract);//false;
Console.WriteLine(typeStudent.IsAbstract);//false
Console.WriteLine(typeIFlyable.IsAbstract);//true
Console.WriteLine(typeMyAbsClass.IsAbstract);//true
Console.WriteLine(typeMyStaticClass.IsAbstract); //true
Console.ReadKey();

 

上述就是是反射的组成部分介绍和部分放的核心用法······

相关文章