C#_使用委托及反射(Reflection)

一:反射(Reflection)

反射指程序可以访问、检测和修改它本身状态或行为的一种能力

程序集包含模板,而模板包含模型,类型有包含成员。反射则提供了封装程序集,模块和类型的对象。

您可以使用反射动态的创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性

优缺点:

优点:

1.反射提高了程序的灵活性和拓展性。

2.降低耦合性,提高自适应能力。

3.它允许程序创建和控制任何类的对象,无序提前编码目标类。

缺点:

        1.性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和拓展性要求很高的系统框架上,普通程序不建议使用。

        2.使用反射会模糊程序内部逻辑;程序员希望在源代码中看到程序的逻辑,反射却绕过了源代码的技术,因而会带来维护的问题,反射代码比相应的直接代码更复杂。

反射(Reflection)的用途

  • 它允许在运行时查看特性(Attribuate)信息
  • 它允许审查集合中的各种类型,以及实例化这些类型
  • 它允许延迟绑定的方法和属性(property)
  • 它允许在运行时创建新类型,然后使用这些类型执行一些任务

查看元数据:

我们已经在上面的章节中提到过,使用反射(Reflection)可以查看特性(Attribuate)信息

System.Reflection类的Memberinfo对象需要被初始化,用于发现与类相关的特性(Attribuate)。为了做到这点,您可以定义目标类的一个对象,如下:

`System.Reflection.MemberInfo info = typeof(MyClass);

下面的程序演示了这点:

[AttributeUsage(AttributeTargets.All)]
public class HelpAttribute : System.Attribute
{
    public readonly string Url;

    private string topic;
    public string Topic  // Topic 是一个命名(named)参数
    {
        get
        {
            return topic;
        }
        set
        {

            topic = value;
        }
    }

    public HelpAttribute(string url)  // url 是一个定位(positional)参数
    {
        this.Url = url;
    }
    
}
[HelpAttribute("Information on the class MyClass")]
class MyClass
{
}
internal class Program
{
    [STAThread]
    static void Main()
    {
        System.Reflection.MemberInfo info = typeof(MyClass);
        object[] attributes = info.GetCustomAttributes(true);
        for (int i = 0; i < attributes.Length; i++)
        {
            System.Console.WriteLine(attributes[i]);
        }

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}

当上面的代码被编译和执行时,它会显示附加到类MyClass上的自定义特性:HelpAttribute

实例

在本实例中,我们将使用在上一章中创建的 DeBugInfo 特性,并使用反射(Reflection)来读取 Rectangle 类中的元数据。

using System;
using System.Diagnostics;
using System.Reflection;
using System.Windows.Forms;

namespace test
{
    // 一个自定义特性 BugFix 被赋给类及其成员
    [AttributeUsage(AttributeTargets.Class |
    AttributeTargets.Constructor |
    AttributeTargets.Field |
    AttributeTargets.Method |
    AttributeTargets.Property,
    AllowMultiple = true)]

    public class DeBugInfo : System.Attribute
    {
        private int bugNo;
        private string developer;
        private string lastReview;
        public string message;

        public DeBugInfo(int bg, string dev, string d)
        {
            this.bugNo = bg;
            this.developer = dev;
            this.lastReview = d;
        }

        public int BugNo
        {
            get
            {
                return bugNo;
            }
        }
        public string Developer
        {
            get
            {
                return developer;
            }
        }
        public string LastReview
        {
            get
            {
                return lastReview;
            }
        }
        public string Message
        {
            get
            {
                return message;
            }
            set
            {
                message = value;
            }
        }
    }
    [DeBugInfo(45, "Zara Ali", "12/8/2012",
         Message = "Return type mismatch")]
    [DeBugInfo(49, "Nuha Ali", "10/10/2012",
         Message = "Unused variable")]
    class Rectangle
    {
        // 成员变量
        protected double length;
        protected double width;
        public Rectangle(double l, double w)
        {
            length = l;
            width = w;
        }
        [DeBugInfo(55, "Zara Ali", "19/10/2012",
             Message = "Return type mismatch")]
        public double GetArea()
        {
            return length * width;
        }
        [DeBugInfo(56, "Zara Ali", "19/10/2012")]
        public void Display()
        {
            Console.WriteLine("Length: {0}", length);
            Console.WriteLine("Width: {0}", width);
            Console.WriteLine("Area: {0}", GetArea());
        }
    }//end class Rectangle

    internal class Program
    {
        [STAThread]
        static void Main()
        {
            Rectangle r = new Rectangle(4.5, 7.5);
            r.Display();
            Type type = typeof(Rectangle);

            Console.WriteLine("----------");

            // 遍历 Rectangle 类的特性
            foreach (Object attributes in type.GetCustomAttributes(false))
            {
                DeBugInfo dbi = (DeBugInfo)attributes;
                if (null != dbi)
                {
                    Console.WriteLine("Bug no: {0}", dbi.BugNo);
                    Console.WriteLine("Developer: {0}", dbi.Developer);
                    Console.WriteLine("Last Reviewed: {0}",dbi.LastReview);
                    Console.WriteLine("Remarks: {0}", dbi.Message);
                }
            }

            Console.WriteLine("----------");

            // 遍历方法特性
            foreach (MethodInfo m in type.GetMethods())
            {
                foreach (Attribute a in m.GetCustomAttributes(true))
                {
                    DeBugInfo dbi = a as DeBugInfo;
                    if (null != dbi)
                    {
                        Console.WriteLine("Bug no: {0}, for Method: {1}",dbi.BugNo, m.Name);
                        Console.WriteLine("Developer: {0}", dbi.Developer);
                        Console.WriteLine("Last Reviewed: {0}",dbi.LastReview);
                        Console.WriteLine("Remarks: {0}", dbi.Message);
                    }
                }
            }

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

 二:使用委托传递方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace _1使用委托传递方法
{
    internal static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Player p = new Player("亚瑟",100);// 创建主角对象
            Enemy e = new Enemy("安其拉", 100, p);// 创建怪物对象
            // 调用打怪的方法
            p.HitEnemy();

                 

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
    //1 定义委托类型
  public delegate void Method();// 定义委托类型
    public class Player
    {
        public string Name {  get; set; }
        public int Atk {  get; set; }

        // 2定义委托变量
        public Method HitHandle;  // HitHandle=BeHit
        public Player( string n,int a)
        {
            Name = n;
            Atk = a;
        }

        public void HitEnemy()
        {
            Console.WriteLine(Name+"主角来了,要开始打人了");
            //4 使用委托变量 其实等于调用委托方法
            HitHandle();// 其实就是调用BeHit方法
        }
    }

    public class Enemy
    {
       
        public string EnemyName { get; set; }
        public int HP { get; set; }

        public Enemy(string e,int h,Player p)
        {
            //3 给 HitHandle 委托变量赋值,需要对象.HitHandle=BeHit
            EnemyName = e;
            HP = h;
            p.HitHandle= BeHit;
        }

        public  void BeHit()
        {
            Console.WriteLine(EnemyName+"说;不行了 要被打死了");
        }

    }
}

//利用委托(Delegate)和委托的多播实现以下效果:
//有一个游戏玩家类:Player,有 Name 姓名属性,有 Attack 攻击力属性,有一个 HitEmemy 打怪方法
//有一个怪物类:Enemy,有 EnemyName 姓名属性,有 Hp 血量属性,有一个 BeHit 被打掉血方法
//实现玩家打怪掉血的效果

OK搞定🆗Σ(っ °Д °;)っ///

  • 12
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值