You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用未知参数数组调用C# DynamicObject的TryInvoke方法?

用参数数组调用DynamicObject的可行方案

方法一:借助DLR内置的InvokeBinder(推荐)

不需要自行实现InvokeBinder,.NET通过Microsoft.CSharp.RuntimeBinder.Binder类提供了现成的创建逻辑。只需引用Microsoft.CSharp程序集(.NET Core/.NET 5+需安装同名NuGet包),就能快速构造可用的InvokeBinder实例,直接调用TryInvoke方法。

示例代码:

using System.Dynamic;
using Microsoft.CSharp.RuntimeBinder;

// 自定义DynamicObject示例
public class MyDynamicObj : DynamicObject
{
    public override bool TryInvoke(InvokeBinder binder, object?[]? args, out object? result)
    {
        result = $"执行调用,参数列表:{string.Join(", ", args ?? Array.Empty<object>())}";
        return true;
    }
}

// 调用逻辑
var dynObj = new MyDynamicObj();
object[] paramArray = new object[] { "参数1", 123, false };

// 创建InvokeBinder实例
var invokeBinder = Binder.Invoke(
    CSharpBinderFlags.None,
    null,
    typeof(Program), // 替换为你的当前类类型
    new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }
);

// 执行调用
if (dynObj.TryInvoke(invokeBinder, paramArray, out var invokeResult))
{
    Console.WriteLine(invokeResult);
}

方法二:动态调用结合参数展开(适合参数数量有限的场景)

如果不想直接操作TryInvoke,可以封装一个辅助方法,利用dynamic特性结合params实现参数数组的展开调用:

public static dynamic InvokeDynamicTarget(dynamic target, params object[] args)
{
    return args switch
    {
        [] => target(),
        [var a] => target(a),
        [var a, var b] => target(a, b),
        [var a, var b, var c] => target(a, b, c),
        [var a, var b, var c, var d] => target(a, b, c, d),
        // 可根据业务需求扩展更多参数分支
        _ => throw new ArgumentException("未处理的参数数量")
    };
}

// 使用示例
var dynObj = new MyDynamicObj();
object[] paramArray = new object[] { "参数1", 123, false };
var result = InvokeDynamicTarget(dynObj, paramArray);
Console.WriteLine(result);

这种方法的局限性是参数数量较多时需要编写大量分支,适合参数个数固定且较少的场景。

方法三:自行实现InvokeBinder(不推荐)

虽然可以自定义InvokeBinder,但DLR的绑定逻辑复杂,自行实现容易引发异常,仅适合测试场景:

public class CustomInvokeBinder : InvokeBinder
{
    public CustomInvokeBinder(CallInfo callInfo) : base(callInfo) { }

    public override DynamicMetaObject FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
    {
        // 简单实现抛出异常,实际场景需完善绑定逻辑
        return errorSuggestion ?? new DynamicMetaObject(
            Expression.Throw(Expression.Constant(new NotImplementedException()), typeof(object)),
            BindingRestrictions.Empty
        );
    }
}

// 使用示例
var dynObj = new MyDynamicObj();
object[] paramArray = new object[] { "参数1", 123, false };
var callInfo = new CallInfo(paramArray.Length);
var customBinder = new CustomInvokeBinder(callInfo);

dynObj.TryInvoke(customBinder, paramArray, out var result);
Console.WriteLine(result);

内容的提问来源于stack exchange,提问作者user10619713

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 20:10:07