我看过几篇关于如何做到这一点的帖子。答案都依赖于将Action放在字典中。然而,我遇到的问题是我需要将带有未知签名的Actions传递给方法,而不是字典中。
我有使用以下方法的现有代码。我想添加一个重载,这样我就可以保持与现有代码的兼容性。
// Collection of notification observers.
private static Dictionary<string, List<NotificationObserver>> _Observers = new Dictionary<string, List<NotificationObserver>>();
public static SynchronizationContext Context { get; set; }
public static void RegisterObserver(object observer, string notification, Action<object, Dictionary<string, object>> action)
{
// We only register valid objects.
if (string.IsNullOrWhiteSpace(notification) || action == null || observer == null) return;
// Create a new NotificationObserver object.
// Currently you provide it a reference to the observer. This is not used anywhere; there are plans to use this.
var registeredObserver = new NotificationObserver(observer, action);
// Make sure the notification has already been registered.
// If not, we add the notification to the dictionary, then add the observer.
if (_Observers.ContainsKey(notification))
_Observers[notification].Add(registeredObserver);
else
{
var observerList = new List<NotificationObserver>();
observerList.Add(registeredObserver);
_Observers.Add(notification, observerList);
}
}
public static void PostNotification(object sender, string notification, Dictionary<string, object> userData = null)
{
// Make sure the notification exists.
if (_Observers.ContainsKey(notification))
{
// Loop through each objects in the collection and invoke their methods.
foreach (NotificationObserver observer in _Observers[notification].Where(obs => obs != null))
{
if (Context == null)
observer.Action(sender, userData);
else
{
Context.Send((state) => observer.Action(sender, userData), null);
}
}
// Clean ourself up.
Task.Run(new Action(() =>
{
PurgeNullObservers();
}));
}
}
通知观察员
internal sealed class NotificationObserver
{
internal NotificationObserver(object observer, Action<object, Dictionary<string, object>> action)
{
this.Observer = observer;
this.Action = action;
}
internal object Observer { get; private set; }
internal Action<object, Dictionary<string, object>> Action { get; private set; }
}
我想在我的代码库中执行以下操作:
NotificationManager.RegisterObserver(this.SomeProperty, "SomeString", this.SomeProperty.DoStuff);
NotificationManager.RegisterObserver(this.Logger, "LogInfo", this.Logger.LogInfo);
基本上,我想为第三方库对象提供支持,我无权访问源代码,并且无法添加与我预先确定的Action签名匹配的方法。对于大量不同的签名变化,我也不想要30次重载。
任何人都知道有一个很好的方式来完成这个?如果我必须修改我的RegisterObserver和NotificationObserver,我希望这样做,而不必修改现有的方法签名,只需添加一个重载。
提前致谢!
答案 0 :(得分:1)
为什么不在构造RegisterObserver调用时使用lambda expresssion?
NotificationManager.RegisterObserver(this.ThirdParty,
"ThirdPartyData",
(i,j) =>
{
// call the third party method
this.ThirdParty.ThirdPartyMethod(null, false, i);
// other custom logic here using j (the action dictionary)
});
只要您拥有“适应”第三方通话所需的信息以与您现有的签名兼容,您就没有问题。您将自动捕获由lambda表达式创建的闭包中的所有此类信息。