c# - 带有参数的方法的签名是什么?
问题描述
我正要以Expression.Lambda
编程方式绑定(因为未知/可变类型参数),发现如果目标方法使用params
,反射调用与直接调用有点不同。
首先,在官方文档中,“签名”(虽然这更像是 XML-doc):
public static
System.Linq.Expressions.Expression<TDelegate>
Lambda<TDelegate>(
System.Linq.Expressions.Expression body,
params System.Linq.Expressions.ParameterExpression[]? parameters
);
请注意,第二个参数被标记为可选,我们可以写Expression.Lambda<T>(...)
. 如果在 Visual Studio 中,你转到反汇编的声明列表,你可以看到:
public static
Expression<TDelegate>
Lambda<TDelegate>(
Expression body,
params ParameterExpression[] parameters
);
第二个参数不再标记为选项。现在,当我尝试使用反射调用此方法时:
var lambdaFactory = typeof(Expression)
.GetMethods()
// Filter overloads
.Single(x => x.ToString() == "System.Linq.Expressions.Expression`1[TDelegate] Lambda[TDelegate](System.Linq.Expressions.Expression, System.Linq.Expressions.ParameterExpression[])")
.MakeGenericMethod(myTypeArgument);
var lambda = (LambdaExpression) lambdaFactory.Invoke(
null,
new object[] {
...
// ,null
}
);
,我得到了TargetParameterCountException: Parameter count mismatch.
。但是如果null
作为另一个参数添加,它就可以完美地工作。
这对我来说有点奇怪。为什么 MS Docs 使用?
(可选标记)?该params
参数是否真的是可选的,类似于常规选项参数,例如string Foo(int a = 1); var result = Foo();
?或者它只是一个语法糖?所以这就是为什么我可以直接Expression.Lambda<T>(...)
在编辑器中调用,但编译的代码可以不同(这也与反射系统兼容)。如果是这样,这是否意味着该方法总是接收该null
值,即使我没有指定值?但是,如果一个方法使用params
参数,并且没有传递任何内容,则方法体中的参数是一个有效的数组,带有.Count == 0
,而不是null
。使用反射传递是否安全null
,或者我应该创建一个空对象数组?
解决方案
文档中的?
表示可为空的引用类型,而不是可选参数。可空引用类型纯粹是“编译时检查”的事情,在运行时,它们与常规的旧引用类型没有什么不同。:
可空引用类型不是新的类类型,而是对现有引用类型的注释。编译器使用这些注释来帮助您在代码中找到潜在的空引用错误。不可空引用类型和可空引用类型之间没有运行时差异。编译器不会为不可为空的引用类型添加任何运行时检查。好处在于编译时分析。编译器会生成警告,帮助您查找和修复代码中潜在的空错误。您声明您的意图,当您的代码违反该意图时,编译器会警告您。
这解释了为什么?
当您查看“反汇编声明列表”时消失。
一切都?
告诉你,你可以传递null
给这个参数并且该方法仍然有效。
在这种情况下,传递 null 的替代方法是传递一个空数组ParameterExpression
s:
var lambda = (LambdaExpression) lambdaFactory.Invoke(
null,
new object[] {
someBodyExpression,
new ParameterExpression[] { }
}
);
这将反映您如何Lambda
非反射地调用:
// I'm passing no extra arguments, so an empty array is passed to the "params" parameter
Lambda<T>(someBodyExpression)
推荐阅读
- java - 使用 Completablefuture 限制 API 速率以进行异步处理
- php - 从一对多关系中检索图像
- python - 在 CMD 中运行一个类
- r - 使用 R 中的向量调用嵌套 for 循环中的函数的特定数据框列
- sql-server - BCP 实用程序 SQL Server 导出到 CSV - 永远不会创建目标 CSV 文件
- css - 如何截断表格列中的文本?
- html - iOS safari:滚动在内部位置被破坏:已修复;元素
- vue.js - 如何将数据放入 in a component with Vue
I am trying to do a pagination but I can not put the dynamic total I am doing like this:
<v-pagination v-model="currentPage" :page-count="total"
- javascript - React.js 中 Hangman 游戏的对象比较
- python - How can I return display values for all selected fields and field names in QuerySet?