我想为对象的所有方法添加一个公共回调函数。我找到了this SO question,但在那个方法中,我将不得不修改该类的每个功能。我想定义一些beforeFilter
方法,在每次方法调用之前都会被触发。我知道我可以使用Action delegates
,但我不知道如何。
更新:举个例子,我想要的是这样的
Class MyClass
Sub MyCallback
'callback code...
End Sub
'Rest of tyhe code
End Class
正如您所看到的,理想情况是添加一个简单(或多个)方法以在所有其他方法之前进行三重处理。也许有一些基类或界面,我不知道(这就是我要求的原因)。
我认为可能存在的其他选项是克隆对象并定义新类,而不是将代码添加到现有类中。因此Class
使用Object
来访问Type
Class NewClass
Sub AddCallback(Obj As Object, Callback As Action)
'Add the callback here
End Sub
End Class
我只是猜测,也许我的一些选择甚至是不可行的,所以请帮助我这个
最贴近的方法
我现在拥有的是这种方法
Sub RunWithCallback(beforFilter As Action, f As Action)
beforeFilter()
f()
End Sub
(这意味着RunWithCallback
使用Action
和Func
个委托来管理子和函数的大量重载,具有不同数量的参数)这个,我必须运行这个Sub而不是调用任何Object方法(传递ByRef
参数来捕获函数中的返回值)。像这样的东西
Public Sub DoNothing()
Debug.WriteLine("Callback working!")
End Sub
Public Sub BeforeFilter()
Debug.WriteLine("Testing callback...")
End Sub
'To run the above function
RunWithCallback(AddressOf BeforeFilter, AddressOf DoNothing)
我认为应该有一个更好的解决方案,允许避免调用相同的子,并避免重载,对象类的某种动态扩展方法
答案 0 :(得分:1)
以下是代表如何工作以及如何使用它们的示例:
public class MyClass
{
// MyDelegate callback holder
private MyDelegate _myDelegate;
// Singleton holder
private static volatile MyClass _instance;
///<summary>
/// Instance property
///</summary>
public static MyClass Instance
{
get
{
if (_instance == null)
{
_instance = new MyClass();
}
_instance.MyCallbacks(_instance.MyDelegateCallback, _instance.MyDelegateCallback1);
return _instance;
}
}
///<summary>
/// Instance multi-callback caller
///</summary>
///<param name="callbacks">calbacks to call</param>
///<returns>MyClass</returns>
public static MyClass Instance(params MyDelegate[] callbacks)
{
if (_instance == null)
{
_instance = new MyClass();
}
_instance.MyCallbacks(callbacks);
return _instance;
}
///<summary>
/// MyClass constructor
///</summary>
private MyClass()
{
// Define the callback
MyDelegate = MyDelegateCallback;
}
///<summary>
/// MyDelegate property, here u can change the callback to any function which matches the structure of MyDelegate
///</summary>
public MyDelegate MyDelegate
{
get
{
return _myDelegate;
}
set
{
_myDelegate = value;
}
}
///<summary>
/// Call all given callbacks
///</summary>
///<param name="callbacks">callbacks u want to call</param>
public void MyCallbacks(params MyDelegate[] callbacks)
{
if (callbacks != null)
{
foreach (MyDelegate callback in callbacks)
{
if (callback != null)
{
callback.Invoke(null);
}
}
}
}
///<summary>
/// RunTest, if u call this method the defined callback will be raised
///</summary>
public void RunTest()
{
if (_myDelegate != null)
{
_myDelegate.Invoke("test");
}
}
///<summary>
/// MyDelegateCallback, the callback we want to raise
///</summary>
///<param name="obj"></param>
private void MyDelegateCallback(object obj)
{
System.Windows.MessageBox.Show("Delegate callback called!");
}
///<summary>
/// MyDelegateCallback1, the callback we want to raise
///</summary>
///<param name="obj"></param>
private void MyDelegateCallback1(object obj)
{
System.Windows.MessageBox.Show("Delegate callback (1) called!");
}
}
///<summary>
/// MyDelegate, the delegate function
///</summary>
///<param name="obj"></param>
public delegate void MyDelegate(object obj);
我更新了我的答案,看看MyCallbacks(params MyDelegate[] callbacks)
。它会调用与MyDelegate
结构相匹配的不同回调。
编辑:
添加了MyClass.Instance
&amp; MyClass.Instance(params MyDelegate[] callbacks)
。
答案 1 :(得分:1)
你有没有考虑过使用Aspect库?直到你的问题,似乎你真的可以用这种方法解决你的问题。
例如,您可以在此处使用PostSharp
library,只需派生OnMethodBoundaryAspect
class,并处理四个可用的主要事件:
或另外两个:
或其中任何一个。简单的架构是:
int MyMethod(object arg0, int arg1)
{
OnEntry();
try
{
// YOUR CODE HERE
OnSuccess();
return returnValue;
}
catch ( Exception e )
{
OnException();
}
finally
{
OnExit();
}
}
因此您可以轻松调用Callback
函数(并且可以在OnSuccess
方法中提取运行时传递的参数:
public override void OnSuccess(MethodExecutionArgs args)
{
CallBack(GetValueYouNeed(args));
}
PostSharp的简单版本是一个免费许可证,并且有很好的文档记录,因此我强烈建议您研究这种方法。