现在我有一个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。
感谢。
答案 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
检查。如果您可以删除不必要的条件检查,则代码总是更容易编写和读取。