C#如何判断委托是实例方法还是静态方法
一. 委托的分类
通过用什么类型的方法来声明为委托,可以分为两类:
1. 委托静态方法:把一个静态方法给委托
2. 委托实例方法:把一个实例对象的成员方法给委托
(这两个名字是博主取的,可能不是很专业只是为了好区分)
二. 原理部分
委托是将函数指针和实例对象打包在一起的类,它有两个重要的成员,一个用来保存实例对象,一个用来保存函数的指针。从源码中我们可以查看System.Delegate,如下:
1. 将会调用方法所在的对象
// _target is the object we will invoke on
[System.Security.SecurityCritical]
internal Object _target;
2. 将会调用的方法指针
// _methodPtr is a pointer to the method we will invoke
// It could be a small thunk if this is a static or UM call
[System.Security.SecurityCritical]
internal IntPtr _methodPtr;
另外,我们查看System.Delegate的属性,我们可以看到一个属性 Target
public Object Target
{
get
{
return GetTarget();
}
}
来看一下这个 GetTarget() 方法的功能
[System.Security.SecuritySafeCritical]
internal virtual Object GetTarget()
{
return (_methodPtrAux.IsNull()) ? _target : null;
}
可以看到这边有一个字段 _methodPtrAux,这是一个IntPtr类型的指针,可以看到注释可以看出,当把一个静态方法给委托的时候,将会返回一个 null,如果是一个实例方法的时候,将会返回当前方法所在的实例对象(this)
// In the case of a static method passed to a delegate, this field stores
// whatever _methodPtr would have stored: and _methodPtr points to a
// small thunk which removes the "this" pointer before going on
// to _methodPtrAux.
[System.Security.SecurityCritical]
internal IntPtr _methodPtrAux;
三. 测试代码
测试类 Test.cs:
public class Test
{
/// <summary>
/// 实例方法
/// </summary>
public void ShowHelloWorld1()
{
Console.WriteLine("Hello World! -- 1");
} /// <summary>
/// 静态方法
/// </summary>
public static void ShowHelloWorld2()
{
Console.WriteLine("Hello World! -- 2");
}
}
委托声明:
public delegate void ShowHelloWorldMethod();
上端测试代码:
//声明测试对象
Test test = new Test(); //构造实例方法的委托
ShowHelloWorldMethod del = test.ShowHelloWorld1; //判断一下Target是不是指向方法所在的对象
Console.WriteLine(del.Target is Test);//True //调用一下
((Test)del.Target).ShowHelloWorld1();//Hello World! -- 1 //构造静态方法的委托
ShowHelloWorldMethod del2 = Test.ShowHelloWorld2; //判断一下Target是不是null
Console.WriteLine(del2.Target == null);//true
测试结果符合我们的预期:

四. 总结
如果委托的Target属性为null说明是静态方法的委托,如果委托的Target属性不为null说明是实例方法的委托。
C#如何判断委托是实例方法还是静态方法的更多相关文章
- 关于python的类方法、实例方法和静态方法区别
python的类方法需要在方法前面加装饰器:@classmethod ,静态方法是在方法前面加装饰器:@staticmethod. 类方法.类属性是属于类自身,属于类自身的命名空间,和实例方法.实例属 ...
- Python高级笔记(五)--实例方法、静态方法和类方法
1. 类属性.实例属性 类属性在内存中只保存一份 实例属性在每个对象中都要保持一份 obj.__class__.country="xxx": 可以修改类属性 2. 实例方法.静态方 ...
- Python类变量,实例变量,类方法,实例方法,静态方法的分析
Python作为动态语言,跟静态语言如c/c++有很大区别,其中的一个重要的特性就是Python的变量无需声明直接可用.同样,类的成员变量无需声明,直接可用.目的是为了动态语言跟灵活,在思路想到的时候 ...
- python3类方法,实例方法和静态方法
今天简单总结下python的类方法,实例方法,静态方法. python默认都是实例方法,也就是说,只能实例对象才能调用这个方法. 那是不是说类方法也只能被类对象本身来调用呢,当然,不是.类方法既可以被 ...
- Python Class 的实例方法/类方法/静态方法
实例方法.类方法.静态方法 class MyClass(object): class_name = "MyClass" # 类属性, 三种方法都能调用 def __init__(s ...
- [Python3 填坑] 017 实例方法、静态方法、类方法的区别
目录 1. print( 坑的信息 ) 2. 开始填坑 2.1 先上例子 2.2 分析 1. print( 坑的信息 ) 挖坑时间:2019/04/07 明细 坑的编码 内容 Py024-1 实例方法 ...
- 面向对象~~类的成员: 私有成员,公有成员, 实例方法, 类方法, 静态方法, 属性(property), isinstance ,issubclass, 元类(type)
一 私有成员公有成员 公有成员: 在任何地方都能访问 私有成员: 只有在类的内部才能访问 类从加载时,只要遇到类中的私有成员,都会在私有成员前面加上_类名 二 实例方法 实例方法就是类的实例能够使用的 ...
- Python绑定方法,未绑定方法,类方法,实例方法,静态方法
>>> class foo(): clssvar=[1,2] def __init__(self): self.instance=[1,2,3] def hehe(self): pr ...
- python中的实例方法、静态方法、类方法、类变量和实例变量
class MyTest: myname = 'peter' # add a instance attribute def __init__(self, name): self.n ...
随机推荐
- python同步IO编程——StringIO、BytesIO和stream position
主要介绍python两个内存读写IO:StringIO和BytesIO,使得读写文件具有一致的接口 StringIO 内存中读写str.需要导入StringIO >>> from i ...
- 《漫画ERP》经典文章摘抄
1.对企业来说,应用ERP的价值就在于通过系统的计划和控制功能,结合企业的流程优化,有效的配置各项资源,以加快对市场的响应,降低成本,提高效率和效益,从而提升企业的竞争力:
- Android 避免内存泄漏
什么是内存泄露? 就是该回收的内存由于种种原因没有被回收,还驻留在内存中. 内存泄露有什么影响? 可能一处小小的内存泄露就会导致整个应用卡顿,甚至崩溃. 例子说明: Toast.makeText(Ma ...
- linux 删除.svn文件
linux删除当前目录及其子目录下的.svn文件,linux下删除全部的.svn文件 find . -name "*.svn" -type d -print -exec rm -r ...
- 使用Navicat Keygen激活(破解)Navicat Premium 12
1.到Navicat官网下载使用版本进行安装,具体操作不再详述.Navcat官网下载链接:http://www.navicat.com.cn/download/navicat-premium : 2. ...
- CentOS 7 离线环境安装nginx时报错:./configure: error: C compiler cc is not found
先说解决方法: 在nginx目录下,查看objs/autoconf.err文件,该文件记录了具体的错误信息 vi objs/autoconf.err 一般就是缺少一些文件,因为我的gcc.g++也是离 ...
- 带你揭秘Shiro(一)
提到Shiro,不得不先介绍RBAC介绍 RBAC介绍: RBAC是基于角色的访问控制(Role-Based Access Control )在 RBAC 中,权限与角色相关联,用户通过成为适当角色的 ...
- C# 使用.net core 驱动树莓派的IO信号
如何使用.net core来驱动树莓派的IO信号?是我们的实际项目需求中,可能就会有这种小项目,我们要输出一个IO信号,此处我们拿了树莓派4做测试 一共有两排引脚,引脚的顺序定义及功能如下: 我们就参 ...
- 5分钟搞定Jenkis
目录 什么是持续集成 Jenkins简介 Jenkins安装与启动 Jenkins插件安装 全局工具配置 自动安装 本地安装 代码上传至Git服务器 任务的创建与执行 Go项目 JAVA项目 @ 什么 ...
- Python 3.7的安装过程
百度云Pyhton3.7-32位安装包: 链接:https://pan.baidu.com/s/1P5Egkl2KNt_DjhiFaDzqsg提取码:5171 百度云Pyhton3.7-64位安装包: ...