clr via c# delegate
1,委托列子
internal delegate void Feedback(int value);
class DelegateRef
{
public static void StaticDelegateDeomo()
{
Console.WriteLine("---------------static delegate Demo ------------");
Counter(1, 3, null);
Counter(1, 3, FeedBackToConsole);
Counter(1, 3, FeedBackToMsgBox);
Console.WriteLine();
}
public static void InstanceDelegateDemo()
{
Console.WriteLine("----------------Instance Delegate Demo ---------");
DelegateRef p = new DelegateRef();
Counter(1, 3, p.FeedBackToFile);
Console.WriteLine();
}
public static void ChainDelegateDemo1(DelegateRef p)
{
Console.WriteLine("----------------Chain Delegate Demo ----------");
Feedback chain = FeedBackToConsole;
chain += FeedBackToMsgBox;
chain += p.FeedBackToFile;
Counter(1, 2, chain);
Console.WriteLine();
chain -= FeedBackToMsgBox;
Counter(1, 2, chain); }
private static void Counter(int from, int to, Feedback fb)
{
for (int val = from; val <= to; val++)
{
if (fb != null)
fb(val);
}
} private static void FeedBackToConsole(int value)
{
Console.WriteLine("Item=" + value);
}
private static void FeedBackToMsgBox(int value)
{
MessageBox.Show("Item=" + value);
}
private void FeedBackToFile(int value)
{
using(StreamWriter sw=new StreamWriter("Status", true))
{
sw.WriteLine("Item=" + value);
}
}
public static void CallDelegateDemo()
{
StaticDelegateDeomo();
InstanceDelegateDemo();
ChainDelegateDemo1(new DelegateRef());
}
}
2,委托揭秘
在 Conter之中,实际上 +=是创建了Delegate的实列,并且调用了Combine函数,触发调用了invoke函数,移除调用了,remove函数
.method public hidebysig static void ChainDelegateDemo1(class ClrFromCSharp_2_2.LearnDelegate.DelegateRef p) cil managed
// SIG: 00 01 01 12 60
{
// 方法在 RVA 0x2ad4 处开始
// 代码大小 122 (0x7a)
.maxstack 3
.locals init ([0] class ClrFromCSharp_2_2.LearnDelegate.Feedback chain)
IL_0000: /* 00 | */ nop
IL_0001: /* 72 | (70)000207 */ ldstr "----------------Chain Delegate Demo ----------"
IL_0006: /* 28 | (0A)00001C */ call void [mscorlib]System.Console::WriteLine(string)
IL_000b: /* 00 | */ nop
IL_000c: /* 14 | */ ldnull
IL_000d: /* FE06 | (06)000059 */ ldftn void ClrFromCSharp_2_2.LearnDelegate.DelegateRef::FeedBackToConsole(int32)
IL_0013: /* 73 | (06)000051 */ newobj instance void ClrFromCSharp_2_2.LearnDelegate.Feedback::.ctor(object,
native int)
IL_0018: /* 0A | */ stloc.0
IL_0019: /* 06 | */ ldloc.0
IL_001a: /* 14 | */ ldnull
IL_001b: /* FE06 | (06)00005A */ ldftn void ClrFromCSharp_2_2.LearnDelegate.DelegateRef::FeedBackToMsgBox(int32)
IL_0021: /* 73 | (06)000051 */ newobj instance void ClrFromCSharp_2_2.LearnDelegate.Feedback::.ctor(object,
native int)
IL_0026: /* 28 | (0A)00003C */ call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate,
class [mscorlib]System.Delegate)
IL_002b: /* 74 | (02)000017 */ castclass ClrFromCSharp_2_2.LearnDelegate.Feedback
IL_0030: /* 0A | */ stloc.0
IL_0031: /* 06 | */ ldloc.0
IL_0032: /* 02 | */ ldarg.0
IL_0033: /* FE06 | (06)00005B */ ldftn instance void ClrFromCSharp_2_2.LearnDelegate.DelegateRef::FeedBackToFile(int32)
IL_0039: /* 73 | (06)000051 */ newobj instance void ClrFromCSharp_2_2.LearnDelegate.Feedback::.ctor(object,
native int)
IL_003e: /* 28 | (0A)00003C */ call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate,
class [mscorlib]System.Delegate)
IL_0043: /* 74 | (02)000017 */ castclass ClrFromCSharp_2_2.LearnDelegate.Feedback
IL_0048: /* 0A | */ stloc.0
IL_0049: /* 17 | */ ldc.i4.1
IL_004a: /* 18 | */ ldc.i4.2
IL_004b: /* 06 | */ ldloc.0
IL_004c: /* 28 | (06)000058 */ call void ClrFromCSharp_2_2.LearnDelegate.DelegateRef::Counter(int32,
int32,
class ClrFromCSharp_2_2.LearnDelegate.Feedback)
IL_0051: /* 00 | */ nop
IL_0052: /* 28 | (0A)000049 */ call void [mscorlib]System.Console::WriteLine()
IL_0057: /* 00 | */ nop
IL_0058: /* 06 | */ ldloc.0
IL_0059: /* 14 | */ ldnull
IL_005a: /* FE06 | (06)00005A */ ldftn void ClrFromCSharp_2_2.LearnDelegate.DelegateRef::FeedBackToMsgBox(int32)
IL_0060: /* 73 | (06)000051 */ newobj instance void ClrFromCSharp_2_2.LearnDelegate.Feedback::.ctor(object,
native int)
IL_0065: /* 28 | (0A)00003F */ call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate,
class [mscorlib]System.Delegate)
IL_006a: /* 74 | (02)000017 */ castclass ClrFromCSharp_2_2.LearnDelegate.Feedback
IL_006f: /* 0A | */ stloc.0
IL_0070: /* 17 | */ ldc.i4.1
IL_0071: /* 18 | */ ldc.i4.2
IL_0072: /* 06 | */ ldloc.0
IL_0073: /* 28 | (06)000058 */ call void ClrFromCSharp_2_2.LearnDelegate.DelegateRef::Counter(int32,
int32,
class ClrFromCSharp_2_2.LearnDelegate.Feedback)
IL_0078: /* 00 | */ nop
IL_0079: /* 2A | */ ret
} // end of method DelegateRef::ChainDelegateDemo1
}
3,利用GetInvocationList()的方式,显示调用每一个委托,这样可以显式的处理每个委托的返回值和异常,否则
- 当出现异常的时候,链表里面的下面的委托不会执行
- 当出现阻塞时候,链表里面的下面的委托不会执行
4,委托和反射
internal static class DelegateReflection {
// Here are some different delegate definitions
private delegate Object TwoInt32s(Int32 n1, Int32 n2);
private delegate Object OneString(String s1);
public static void Go(String[] args) {
if (args.Length < 2) {
String fileName = Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly().Location);//获取执行文件的名称,但是没用
String usage =//提示用法
@"Usage:" +
"{0}{1} delType methodName [Arg1] [Arg2]" +
"{0} where delType must be TwoInt32s or OneString" +
"{0} if delType is TwoInt32s, methodName must be Add or Subtract" +
"{0} if delType is OneString, methodName must be NumChars or Reverse" +
"{0}" +
"{0}Examples:" +
"{0} {1}TwoInt32s Add 123 321" +
"{0} {1}TwoInt32s Subtract 123 321" +
"{0} {1}OneString NumChars \"Hello there\"" +
"{0} {1}OneString Reverse \"Hello there\"";
Console.WriteLine(usage, Environment.NewLine, "DelegateReflection+");
return;
}
// Convert the delType argument to a delegate type
Type delType = Type.GetType(args[0]);//1,利用string返回类型Type...注意:DelegateReflection+TwoInt32s才是其TYPE
if (delType == null) {
Console.WriteLine("Invalid delType argument: " + args[0]);
return;
}
Delegate d;
try {
// Convert the Arg1 argument to a method//注意,在某个类里面获取某个方法..方法名是arg[1],Add
MethodInfo mi = typeof(DelegateReflection).GetMethod(args[1], BindingFlags.NonPublic | BindingFlags.Static);//2,获取类中方法
// Create a delegate object that wraps the static method
d = Delegate.CreateDelegate(delType, mi);//3,利用该方法将类的静态方法--->传送至委托.
}
catch (ArgumentException) {
Console.WriteLine("Invalid methodName argument: " + args[1]);
return;
}
// Create an array that that will contain just the arguments
// to pass to the method via the delegate object
Object[] callbackArgs = new Object[args.Length - 2];
if (d.GetType() == typeof(TwoInt32s)) {//类型比较
try {
// Convert the String arguments to Int32 arguments
for (Int32 a = 2; a < args.Length; a++)
callbackArgs[a - 2] = Int32.Parse(args[a]);
}
catch (FormatException) {
Console.WriteLine("Parameters must be integers.");
return;
}
}
if (d.GetType() == typeof(OneString)) {
// Just copy the String argument
Array.Copy(args, 2, callbackArgs, 0, callbackArgs.Length);
}
try {
// Invoke the delegate and show the result
Object result = d.DynamicInvoke(callbackArgs);//4,调用委托,动态给与参数.参数是object[]---必须匹配.
Console.WriteLine("Result = " + result);
}
catch (TargetParameterCountException) {
Console.WriteLine("Incorrect number of parameters specified.");
}
}
// This callback method takes 2 Int32 arguments
private static Object Add(Int32 n1, Int32 n2) {
return n1 + n2;
}
// This callback method takes 2 Int32 arguments
private static Object Subtract(Int32 n1, Int32 n2) {
return n1 - n2;
}
// This callback method takes 1 String argument
private static Object NumChars(String s1) {
return s1.Length;
}
// This callback method takes 1 String argument
private static Object Reverse(String s1) {
Char[] chars = s1.ToCharArray();
Array.Reverse(chars);
return new String(chars);
}
}
- 新建委托TYPE
- 从类中查找静态方法
- 利用Delegate.CreateDelegate建立类中静态方法的委托.
- 利用d.DynamicInvoke(object[])来调用委托,其中参数是一个数组匹配原静态方法的参数.如果不一致会报参数不匹配错误.
- TargetParameterCountException
clr via c# delegate的更多相关文章
- 公共语言运行库(CLR)开发系列课程(2):Pinvoke 进阶 学习笔记
上一章地址 API版本 具有字符串参数的API通常有两种版本 GetWindowText GetWindowTextA GetWindowTextW 缺省情况下CLR会自动寻找合适的匹配 CharSe ...
- LuaInterface简介
Lua是一种很好的扩展性语言,Lua解释器被设计成一个很容易嵌入到宿主程序的库.LuaInterface则用于实现Lua和CLR的混合编程. (一)Lua from the CLR 测试环境:在VS2 ...
- [整理]Unity3D游戏开发之Lua
原文1:[Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘(上) 各位朋友,大家好,我是秦元培,欢迎大家关注我的博客,我地博客地址是blog.csdn.net/qinyuanpei.如果 ...
- LuaInterface简单介绍
LuaInterface简单介绍 Lua是一种非常好的扩展性语言.Lua解释器被设计成一个非常easy嵌入到宿主程序的库.LuaInterface则用于实现Lua和CLR的混合编程. (一)Lua f ...
- ILRuntime 学习
ILRuntime: https://github.com/Ourpalm/ILRuntime Demo: https://github.com/Ourpalm/ILRuntimeU3D 中文在线文档 ...
- CLR via C#(12)-委托Delegate
本来按照进度应该学习事件了,可总觉得应该委托在前,事件在后,才好理解. 委托是一个类,它提供了回调函数机制,而且是类型安全的.使用委托可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数 ...
- 《CLR.via.C#第三版》第二部分第12章节 泛型 读书笔记(六)
终于讲到泛型了.当初看到这个书名,最想看的就是作者对泛型,委托,反射这些概念的理解.很多人对泛型的理解停留在泛型集合上,刚开始我也是,随着项目越做越多,对待泛型的认识也越来越深刻. 泛型的概念:泛型是 ...
- CLR VIA C# 学习笔记
第19章 可空类型 1)使用Nullable<T>可将int32的值类型设置为Null,CLR会在Null时默认赋值为0; 如:Nullable<T> x=null; //使用 ...
- CLR via C# 3rd - 08 - Methods
Kinds of methods Constructors Type constructors Overload operators Type con ...
随机推荐
- Linux 安装tomcat及tomcat自带远程部署项目与管理
准备: 1.Linux系统 2.已经安装好jdk 开始: 选择要安装的tomcat版本:https://archive.apache.org/dist/tomcat/ 我这里使用的是tomcat 8. ...
- 共轭先验(conjugate prior)
共轭是贝叶斯理论中的一个概念,一般共轭要说是一个先验分布与似然函数共轭: 那么就从贝叶斯理论中的先验概率,后验概率以及似然函数说起: 在概率论中有一个条件概率公式,有两个变量第一个是A,第二个是B , ...
- 看完这篇文章,再次遇到Jedis「Redis客户端」异常相信你不再怕了!
本文导读: [1] 疫情当前 [2] 应用异常监控 [3] Redis客户端异常分析 [4] Redis客户端问题引导分析 [5] 站在Redis客户端视角分析 [6] 站在Redis服务端视角分析 ...
- SpringBoot学习遇到的问题(1) - 配置文件有日志的debug模式等配置项,为什么不起作用
这个问题困扰我近乎两天,通过查找N多资料后终于解决,写下来共享给大家. logging.level.root=DEBUG ... 一系列的日志配置项,都不起作用的原因是springboot启动加载不到 ...
- Python小白入门题一——文件增删改
题目描述:用python对文件进行增(创建一个文件).删(删除一个文件).改(重命名)操作. 说明:新建了一个文件夹files存放新增的两个文件,随后这两个文件被批量重命名成“数字.txt”,之后这两 ...
- Docker 容器数据 持久化(系统学习Docker05)
写在前面 本来是可以将数据存储在 容器内部 的.但是存在容器内部,一旦容器被删除掉或者容器毁坏(我亲身经历的痛,当时我们的大数据平台就是运行在docker容器内,有次停电后,不管怎样容器都起不来.以前 ...
- 基于TensorFlow的MNIST手写数字识别-初级
一:MNIST数据集 下载地址 MNIST是一个包含很多手写数字图片的数据集,一共4个二进制压缩文件 分别是test set images,test set labels,training se ...
- Codeforces_723_C
http://codeforces.com/problemset/problem/723/C 将n个数替换为1-m内的数,使得1-m的个数的最小值最大,并且替换步骤最少.注意,不必将每个数都替换!! ...
- JDK11和JDK8类加载器的区别
如下代码: public class Test07 { public static void main(String[] args) throws ClassNotFoundException { / ...
- T1飞跃树林 && 【最长等差子序列】
solution by Mr.gtf 一道简单的递推 首先我们对树高从大到小排序 很容易得到递推式 ans[i]=Σans[j] (j<i && h[j]-h[i]<=K) ...