首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >带仿射的方法的签名是什么?

带仿射的方法的签名是什么?
EN

Stack Overflow用户
提问于 2020-12-24 23:53:31
回答 1查看 254关注 0票数 0

我准备以编程方式绑定Expression.Lambda (因为未知/可变类型参数),并发现如果目标方法使用params,则反射调用与直接调用略有不同。

首先,在正式文件中,“签名”(虽然这更像是XML):

代码语言:javascript
运行
复制
public static
System.Linq.Expressions.Expression<TDelegate>
    Lambda<TDelegate>(
        System.Linq.Expressions.Expression body,
        params System.Linq.Expressions.ParameterExpression[]? parameters
    );

注意,第二个param标记为可选,我们可以编写Expression.Lambda<T>(...)。如果在Visual中,转到反汇编声明列表,则可以看到以下内容:

代码语言:javascript
运行
复制
public static
Expression<TDelegate>
    Lambda<TDelegate>(
        Expression body,
        params ParameterExpression[] parameters
    );

第二个参数不再标记为选项。现在,当我试图使用反射调用此方法时,如下所示:

代码语言:javascript
运行
复制
    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文档使用? (可选标记)?与regualr选项参数类似,params参数真的是可选的,如string Foo(int a = 1); var result = Foo();吗?还是只是一种语法糖?这就是为什么我可以在编辑器中直接调用Expression.Lambda<T>(...),但是编译的代码可能是不同的(这也与反射系统兼容)。如果是这样的话,这是否意味着方法总是接收null值,即使我没有指定值?但是,如果一个方法使用params参数,而没有传递任何内容,则来自方法主体的参数是一个带有.Count == 0的有效数组,而不是null。使用反射传递null是安全的,还是应该创建一个空对象数组?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-25 00:36:24

文档中的?表示可空引用类型,而不是可选参数。可空引用类型纯粹是一种“编译时检查”,而且在运行时,它们与常规的旧引用类型没有什么不同。

可空引用类型不是新的类类型,而是现有引用类型的注释。编译器使用这些注释来帮助您在代码中查找潜在的空引用错误。非空引用类型和可空引用类型之间没有运行时的区别。编译器不添加任何非空引用类型的运行时检查。其好处在于编译时分析。编译器生成警告,帮助您在代码中查找和修复潜在的空错误。您可以声明您的意图,当您的代码违反此意图时,编译器会警告您。

这解释了为什么当您查看“反汇编声明列表”时,?会消失。

所有?告诉您的是,您可以将null传递给该参数,并且该方法仍将工作。

在这种情况下,传递null的另一种方法是传递一个空的ParameterExpression数组:

代码语言:javascript
运行
复制
var lambda = (LambdaExpression) lambdaFactory.Invoke(
        null,
        new object[] {
            someBodyExpression,
            new ParameterExpression[] { }
        }
    );

这将反映您如何非反射地调用Lambda

代码语言:javascript
运行
复制
// I'm passing no extra arguments, so an empty array is passed to the "params" parameter
Lambda<T>(someBodyExpression)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65444177

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档