热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

具有参考变量的C#lambda委托调用方法

以下代码仅适用于没有引用参数的调用方法。publicdelegatevoidtestD2(paramsobject[]args)

以下代码仅适用于没有引用参数的调用方法。

public delegate void testD2(params object[] args);
public static testD2 SetTestD2(MethodInfo method)
{
ParameterExpression param = Expression.Parameter(typeof(object[]),"args");
ParameterInfo[] paramsInfo = method.GetParameters();
Expression[] argsExp = new Expression[paramsInfo.Length];
for (int i = 0; i {
Expression index = Expression.Constant(i);
Type paramType = paramsInfo[i].ParameterType;
//??? ByRef removed from type,becuse Expression.Call with ByRef parametrs lead to compile error
if (paramType.IsByRef == true)
paramType = paramType.GetElementType();
//??? and for this reason is not change of parameters permanent
Expression paramaccessorExp = Expression.ArrayIndex(param,index);
Expression paramCastExp = Expression.Convert(paramaccessorExp,paramType);
argsExp[i] = paramCastExp;
}
var blockExp = Expression.Call(method,argsExp);
LambdaExpression result = Expression.Lambda(typeof(testD2),blockExp,param); //change in param?
return (testD2)result.Compile();
}

我正在考虑更改通过params关键字传递的输入参数,或者为lambda创建新的参数,但是我不知道如何。

public class testCls
{
public void Test()
{
MethodInfo mi = typeof(XXX).GetMethod("TestMethod");
var compiledObject2 = XXX.SetTestD2(mi);
int k = 5;
compiledObject2(k); //k is not passed as ByRef
}
}
public static void TestMethod(ref int a)
{
a = a * a;
}


refout参数与params不兼容,我认为这是基本语言或运行时限制。

要执行所需的操作,可以将其编译为正确类型的强类型委托。 Expression.GetDelegateType呼叫可以为您创建正确的类型;与params object[]不同,可以有输出和参考参数。

,

强类型委托是一种方法,但是对于各种方法需要额外的代码。这就是为什么我尝试使用通用函数来创建通用委托的原因。
对于关键字params,我认为如果该函数被经典地调用DelegateSomeFunc(a,b,c,),则不会通过引用传递任何内容。但是,如果该函数由数组调用,则参数将通过引用传递。

int k = 5;
string b = "aa";
object[] objArr = { k,b };
compiledObject2(k,b); //parameters passed by value
compiledObject2(objArr); //array passed by reference (params don't need create new array?)

代表调用此功能

public static void TestMethod(ref int a,string text)
{
a = a * a;
}

理论上可以用函数创建委托,但是还有另一个问题-用表达式参数数组而不是表达式数组调用函数。
原始帖子中的上面的代码排了一行

var blockExp = Expression.Call(method,argsExp);

但是argsExp可能无法返回函数更改的参数。因此,我将输入参数写在局部表达式变量中,称为函数的函数可以更改,最后将更改后的值放在输入参数数组中。

public static Class1.testD2 SetTestD2(System.Reflection.MethodInfo method)
{
ParameterExpression param = Expression.Parameter(typeof(object[]),"args"); // Expression.Parameter(typeof(object[]),"args");
BinaryExpression[] byExp=null;
Expression[] argsExp = GetArgExp(method.GetParameters(),param,ref byExp);
ParameterExpression xxx = Expression.Variable(typeof(int));
ParameterExpression yyy = Expression.Variable(typeof(string));
var blockExp =
Expression.Block( new[] { xxx,yyy } //variables,Expression.Assign(xxx,argsExp[0]),Expression.Assign(yyy,argsExp[1]),Expression.Call(method,xxx,yyy),Expression.Assign(Expression.ArrayAccess(param,Expression.Constant(0)),Expression.Convert(xxx,typeof(object))) //change input param array
) ;
LambdaExpression result = Expression.Lambda(typeof(testD2),blockExp,param);
return (testD2)result.Compile();
}

该功能只是更改输入参数的示例。现在可以返回更改的参数。

MethodInfo mi = typeof(Class1).GetMethod("TestMethod");
var compiledObject2 = Class1.SetTestD2(mi);
int k = 5;
string b = "aa";
object[] objArr = { k,b); //no changes
compiledObject2(objArr); //objArr[0] changed

但是我不知道函数是否可以修改创建委托的通用委托。


推荐阅读
  • 深入理解Java泛型:JDK 5的新特性
    本文详细介绍了Java泛型的概念及其在JDK 5中的应用,通过具体代码示例解释了泛型的引入、作用和优势。同时,探讨了泛型类、泛型方法和泛型接口的实现,并深入讲解了通配符的使用。 ... [详细]
  • XNA 3.0 游戏编程:从 XML 文件加载数据
    本文介绍如何在 XNA 3.0 游戏项目中从 XML 文件加载数据。我们将探讨如何将 XML 数据序列化为二进制文件,并通过内容管道加载到游戏中。此外,还会涉及自定义类型读取器和写入器的实现。 ... [详细]
  • 从 .NET 转 Java 的自学之路:IO 流基础篇
    本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 在前两篇文章中,我们探讨了 ControllerDescriptor 和 ActionDescriptor 这两个描述对象,分别对应控制器和操作方法。本文将基于 MVC3 源码进一步分析 ParameterDescriptor,即用于描述 Action 方法参数的对象,并详细介绍其工作原理。 ... [详细]
  • 本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 本文详细介绍了如何构建一个高效的UI管理系统,集中处理UI页面的打开、关闭、层级管理和页面跳转等问题。通过UIManager统一管理外部切换逻辑,实现功能逻辑分散化和代码复用,支持多人协作开发。 ... [详细]
  • 本文详细介绍了 Apache Jena 库中的 Txn.executeWrite 方法,通过多个实际代码示例展示了其在不同场景下的应用,帮助开发者更好地理解和使用该方法。 ... [详细]
  • 本文介绍如何使用阿里云的fastjson库解析包含时间戳、IP地址和参数等信息的JSON格式文本,并进行数据处理和保存。 ... [详细]
  • 本文详细介绍了中央电视台电影频道的节目预告,并通过专业工具分析了其加载方式,确保用户能够获取最准确的电视节目信息。 ... [详细]
  • Inthefollowingcode:在以下代码中:intc;while((c10)>0)Whatdoesc10evaluateto?Isit1wh ... [详细]
author-avatar
martinsleibert_471
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有