【问题标题】:Getting the argument names along with values in a dynamic method invoke在动态方法调用中获取参数名称和值
【发布时间】:2012-11-13 18:43:36
【问题描述】:

我正在实施DynamicObject。在TryInvokeMethod 中,除了参数(传递给方法)之外,我还需要参数的名称(如果已使用)。

我可以看到binder.CallInfo.ArgumentNames 确实提供了名称,但我无法将它们与值相关联。有没有办法这样做,还是我希望反对:

public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
    var names = binder.CallInfo.ArgumentNames;
    foreach (var arg in args)
    {
        arguments.Add(new Argument(arg));
    }
    //I need to associate the names and the args
    result = this;
    return true;
}

例如,如果我拨打如下电话:

myDynamicObject.DynamicInvoke("test", something: "test2")

我有test 和test2,还有something,但我无法获得something 是test2 的名称和test 没有名称的信息。

【问题讨论】:

  • 您应该假设最后一个参数名称(如果有)对应于最后一个方法参数,依此类推。
  • @user629926 感谢您的指点。我用它来获取下面的代码。如果您愿意,您仍然可以添加为答案,我会接受。

标签: c# dynamic dynamicobject tryinvokemember


【解决方案1】:

我不得不使用这样一个事实,即命名参数仅在指定非命名参数之后出现(感谢 user629926 指出显而易见的)和初始代码:

var names = binder.CallInfo.ArgumentNames;
var numberOfArguments = binder.CallInfo.ArgumentCount;
var numberOfNames = names.Count;

var allNames = Enumerable.Repeat<string>(null, numberOfArguments - numberOfNames).Concat(names);
arguments.AddRange(allNames.Zip(args, (flag, value) => new Argument(flag, value)));

【讨论】:

  • 一个可能简化代码的选项是使用var allNames = Enumerable.Repeat(null, numberOfArguments - numberOfNames).Concat(names);。然后您可以使用 Enumerable.Zip 将值和名称配对,null 用于未命名的参数。
  • @JonSkeet 不错。我确实重构了上面的代码,但这更整洁。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-03
  • 2015-10-01
  • 1970-01-01
  • 2011-10-09
  • 2016-10-21
相关资源
最近更新 更多