如何传递数组'方法签名C#

时间:2018-01-10 03:25:46

标签: c# expression

现在我有一个ConcurrentDictionary。 我想调用IDataExchangeServiceCallBack的方法。

下面的IDataExchangeServiceCallBack代码:

[ServiceContract]
public interface IDataExchangeServiceCallBack
{
    [OperationContract(IsOneWay = true)]
    void SendResult(string msg);

    [OperationContract(IsOneWay = true)]
    void Receive(List<RealDataModel> models);
}

在其他课程中,我想调用dict的方法foreach。

,例如

    public void Receive(List<RealDataModel> models)
    {
        Broast(o => nameof(o.Receive), models);
    }

    public void SendResult(string msg)
    {
        Broast(o => nameof(o.SendResult), msg);
    }

以下的Broast方法:

    private void Broast(Func<IDataExchangeServiceCallBack, string> funcMethodName, params object[] args)
    {
        if (_callbackChannelList.Count > 0)
        {
            var callbackChannels = _callbackChannelList.ToArray();

            foreach (var channel in callbackChannels)
            {
                try
                {
                    var type = channel.Value.GetType();

                    // fetch the method's name.
                    var methodName = funcMethodName.Invoke(channel.Value);

                    // reflect & get the method
                    var methodInfo = type.GetMethod(methodName);

                    //invoke
                    methodInfo?.Invoke(channel.Value, args);
                }
                catch (Exception ex)
                {
                    _callbackChannelList.TryRemove(channel.Key, out _);
                }
            }
        }
    }

现在我的问题是如何在不反映的情况下实现上述代码,它有更好的解决方案。

Expression可以实现吗?

我不熟悉Expression。

感谢。

1 个答案:

答案 0 :(得分:2)

我不明白你是如何得到你所拥有的解决方案的。无论o的类型如何,表达式(例如nameof(o.Receive))始终会生成字符串"Receive"。在我看来,你可以将nameof(IDataExchangeServiceCallBack.Receive)传递给方法而不是传递委托。

那就是说,我也不明白你为什么要使用反射 Expression。在我看来,在调用网站上,您知道您要处理的对象类型,您要调用的方法,您想要传递的参数。所以你可以传递一个完成所有这一切的委托。例如:

private void Broast(Action<IDataExchangeServiceCallBack> callback)
{
    foreach (var channel in _callbackChannelList.ToArray())
    {
        try
        {
            //invoke
            callback(channel.Value);
        }
        catch (Exception ex)
        {
            _callbackChannelList.TryRemove(channel.Key, out _);
        }
    }

}

用过:

public void Receive(List<RealDataModel> models)
{
    Broast(o => o.Receive(models));
}

public void SendResult(string msg)
{
    Broast(o => o.SendResult(msg));
}

请注意,我已经清理了Broast()方法。在空集合上调用ToArray()的开销非常小,并且它显着简化了代码以删除Count > 0检查。如果您可以删除不必要的条件检查,则代码总是更容易编写和读取。