文档章节

一个例子:C#语言使用反射调用指定类内的函数

北风其凉
 北风其凉
发布于 2016/01/13 23:29
字数 724
阅读 1072
收藏 3

今天研究了一下,当指定程序集、类全名、方法名时,给定一个该类的实例,如何调用该实例中指定的方法。

这个功能的背景是这样的:

1、程序中有多个窗体(都继承自Form),保存在一个数组中

2、因为作为父类的Form我是不能新加入任何方法的,所以代码都是现在每个具体的页面里,也就是说,我们只能在子类中写代码,而不能在基类中写代码

3、每个页面(如FormA、FormB)都有一个功能,实现一个同一名称的函数

4、获取FormA、FormB的实例后,要做到调用这些页面内在第3步中指定名称的函数

这个功能抽象一下,可以表述为:给定程序集、类名、指定的函数名,我们要想办法在得到这个类的实例时,调用到指定的函数


示例程序如下:

设立一个程序集InvokeTester

里面实现基类Vehicle

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

namespace InvokeTester
{
    public class Vehicle
    {
        public Vehicle(string brand, string model)
        {
            this.Brand = brand;
            this.Model = model;
        }

        /// <summary>
        /// 商标
        /// </summary>
        private string _brand;
        /// <summary>
        /// 商标
        /// </summary>
        public string Brand
        {
            get { return _brand; }
            private set { _brand = value; }
        }

        /// <summary>
        /// 型号
        /// </summary>
        private string _model;
        /// <summary>
        /// 型号
        /// </summary>
        public string Model
        {
            get { return _model; }
            private set { _model = value; }
        }
    }
}

Vehicle下有子类Truck:

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

namespace InvokeTester
{
    public class Truck : Vehicle
    {
        public Truck(string brand, string model, string purpose)
            : base(brand, model)
        {
            this.Purpose = purpose;
        }

        /// <summary>
        /// 用途
        /// </summary>
        private string _purpose;
        /// <summary>
        /// 用途
        /// </summary>
        public string Purpose
        {
            get { return _purpose; }
            private set { _purpose = value; }
        }

        public string GetDescription()
        {
            return string.Format("商标:{0},型号:{1},用途:{2}", Brand, Model, Purpose);
        }
    }
}

现在要做的,是在一个以Vehicle类保存的Truck类实例中,给定程序集名称InvokeTester、类名Truck、方法名GetDescription,调用GetDescription方法。代码如下:

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

namespace InvokeTester
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                string dllName = "InvokeTester"; //程序集名
                string className = "InvokeTester.Truck"; //类全名
                string methodName = "GetDescription"; //方法名

                //调用对象的指定方法
                Vehicle vehicle = new Truck("大象牌", "DX001", "起重机");
                Assembly assembly = Assembly.Load(dllName);
                if (assembly != null)
                {
                    Type type = assembly.GetType(className);
                    if (type != null)
                    {
                        MethodInfo methodInfo = type.GetMethod(methodName);
                        if (methodInfo != null)
                        {
                            string desc = methodInfo.Invoke(vehicle, null).ToString();
                            Console.WriteLine(desc);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

            Console.Read();
        }
    }
}

这段代码的执行结果如下:

使用本方法还需要注意一点:

如果被调用的方法在不同的程序集内,请确保这个程序集只生成一个DLL。如果这个程序集生成了多个DLL(可能因为多个生成目标地址不用的程序集都依赖于这个程序集,导致这个程序集的DLL散落在多处),那么在调用MethodInfo类的Invoke函数时可能会报错,异常信息为:“对象与目标类型不匹配”。

END

© 著作权归作者所有

共有 人打赏支持
北风其凉

北风其凉

粉丝 115
博文 498
码字总数 463468
作品 4
朝阳
程序员
私信 提问
【翻译】C#编程语言和JAVA编程语言的比较(上)

【翻译】C#编程语言和JAVA编程语言的比较(上) 原文地址:http://www.25hoursaday.com/CsharpVsJava.html 简介 C#语言是一门面向对象的语言,开发者可以使用C#和微软.NET平台快速构建各种应...

fbf
2013/08/13
0
0
while/Scorpio-CSharp

Scorpio-CSharp author : while QQ群 : 245199668 加群 VSCode 基础语法提示插件 https://marketplace.visualstudio.com/items?itemName=while.scorpio 或者 VSCode 直接搜索 scorpio 脚本教......

while
2016/01/18
0
0
C#语法——反射,架构师的入门基础。

前言 编程其实就是写代码,而写代码目的就是实现业务,所以,语法和框架也是为了实现业务而存在的。因此,不管多么高大上的目标,实质上都是业务。 所以,我认为不要把写代码上升到科学的高度...

kiba518
08/27
0
0
Java 反射机制浅析(重要)

自己对java的运行状态这个概念不理解,但是反射机制的前提就是在运行状态中,所以也必须搞清楚这个概念。 JAVA运行状态:所谓运行状态就是程序已经跑起来了,什么样叫跑起来了? 1、如果用m...

浮躁的码农
2016/02/01
38
0
[C#基础知识系列]专题八: 深入理解泛型(二)

引言:   本专题主要是承接上一个专题要继续介绍泛型的其他内容,这里就不多说了,就直接进入本专题的内容的。 一、类型推断   在我们写泛型代码的时候经常有大量的"<"和">"符号,这样有...

技术小胖子
2017/11/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

jquery通过id显示隐藏

var $div3 = $('#div3'); 显示 $div3.show(); 隐藏 $div3.hide();

yan_liu
57分钟前
1
0
《乱世佳人》读书笔记及相关感悟3900字

《乱世佳人》读书笔记及相关感悟3900字: 之前一直听「荔枝」,后来不知怎的转向了「喜马拉雅」,一听就是三年。上班的时候听房产,买房了以后听装修,兴之所至时听旅行,分手后听亲密关系,...

原创小博客
59分钟前
1
0
大数据教程(9.6)map端join实现

上一篇文章讲了mapreduce配合实现join,本节博主将讲述在map端的join实现; 一、需求 实现两个“表”的join操作,其中一个表数据量小,一个表很大,这种场景在实际中非常常见,比如“订单日志...

em_aaron
今天
1
0
cookie与session详解

session与cookie是什么? session与cookie属于一种会话控制技术.常用在身份识别,登录验证,数据传输等.举个例子,就像我们去超市买东西结账的时候,我们要拿出我们的会员卡才会获取优惠.这时...

士兵7
今天
1
0
十万个为什么之为什么大家都说dubbo

Dubbo是什么? 使用背景 dubbo为什么这么流行, 为什么大家都这么喜欢用dubbo; 通过了解分布式开发了解到, 为适应访问量暴增,业务拆分后, 子应用部署在多台服务器上,而多台服务器通过可以通过d...

尾生
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部