我有一系列功能,我希望具有以下功能。重播功能和參數列表
- 當函數被調用時,其自身添加到的記住參數的功能列表和值
- 允許的功能列表,在以後的日子
不同的功能有一個被稱爲各種不同的參數,我正在努力想辦法做到這一點。任何幫助,將不勝感激。
我有一系列功能,我希望具有以下功能。重播功能和參數列表
不同的功能有一個被稱爲各種不同的參數,我正在努力想辦法做到這一點。任何幫助,將不勝感激。
調用我認爲這將滿足您的需求,但功能沒有「並稱自己」。使函數「添加自己」
public class Recorder
{
private IList<Action> _recording;
public Recorder()
{
_recording = new List<Action>();
}
public void CallAndRecord(Action action)
{
_recording.Add(action);
action();
}
public void Playback()
{
foreach(var action in _recording)
{
action();
}
}
}
//usage
var recorder = new Recorder();
//calls the functions the first time, and records the order, function, and args
recorder.CallAndRecord(()=>Foo(1,2,4));
recorder.CallAndRecord(()=>Bar(6));
recorder.CallAndRecord(()=>Foo2("hello"));
recorder.CallAndRecord(()=>Bar2(0,11,true));
//plays everything back
recorder.Playback();
的一種方法是使用一個AOP LIB如postsharp或李林甫動態代理,並添加一個攔截器這增加了功能和args到陣列。要做到這一點可能會比值得的IMO更多的工作,因爲上述更簡單,並仍然實現所需的功能。
幹得好,這是最棒的! – MrD 2011-12-21 02:44:36
確實,出色的解決方案。 – 2011-12-21 03:16:50
非常好的答案。 +1 – 2011-12-22 03:18:43
我不知道我理解你的問題,但我認爲你可以使用指向數組的指針(在C#中它被稱爲委託)。所以當函數被調用時,把函數指針放在一個列表中。這樣你可以從列表中調用函數。這是一些想法。注意,當您將新代表指針添加到列表(functionPointers
)時,請在第二個列表myParameters
中添加類型爲Parameters
的新對象,該對象在公共屬性parameters
中保存函數參數。這意味着代表i
在參數列表functionPointers
中的參數具有i
列表中的第012個對象myParameters
。這是你如何知道哪些參數,是哪個功能。可能有一些更好的解決方案,但這是替代方案。
delegate void NewDelegate();
class Parameter{
public ArrayList parameters;
}
ArrayList functionPointers=new ArrayList();
ArrayList<Parameter> myParameters=new ArrayList<Parameter>();
NewDelegate myDelegate;
void someFunction(int a, int b){
myDelegate+=someFunction;//you add this function to delegate because this function is called
functionPointers.add(myDelegate);//Add delegete to list
Parameter p=new Parameter();//Create new Parameter object
p.parameters.add(a);//Add function parameters
p.parameters.add(b);
myParameters.add(p);//add object p to myParameters list
}
這段代碼甚至沒有編譯。您無法將任何方法存儲到無參數委託。您必須遵循方法簽名規則。 – 2011-12-21 02:41:00
也許你可以一些如何使用Delegate.DynamicInvoke(Object[] obj)
功能。您可以將每種方法添加到對象數組,然後遍歷每個調用DynamicInvoke的數組。
這幾乎沒有一個優雅的解決方案。既然你說過這些方法都有不同的簽名,那麼就沒有辦法將它們作爲代理存儲在單個數組中。除此之外,接下來您可以嘗試使用反射,將每個參數值存儲在object []中,將方法存儲爲MethodInfo,然後調用它。
編輯:這是我能想出:
private Dictionary<MethodBase, object[]> methodCollection = new Dictionary<MethodBase, object[]>();
public void AddMethod(MethodBase method, params object[] arguments)
{
methodCollection.Add(method, arguments);
}
private void MyMethod(int p1, string p2, bool p3)
{
AddMethod(System.Reflection.MethodInfo.GetCurrentMethod(), new object[] { p1, p2, p3 });
}
private void MyOtherMethod()
{
AddMethod(System.Reflection.MethodInfo.GetCurrentMethod(), new object[] { });
}
然後只需用method.Invoke(method.ReflectedType, args)
+1這更多的是我想說的......但是用DynamicInvoke來做。我以前從來沒有真正使用它,所以我可以離開基地。 – 2011-12-21 02:29:13
要使用DynamicInvoke,您需要Delegate實例,爲此您需要Type和MethodInfo,以便您可以使用'Delegate.CreateDelegate()'創建委託,這與基本相同,只需幾個步驟。你仍然需要反思。 – 2011-12-21 02:37:36
如果要存儲參數以及和有你可以使用FUNC鍵,存儲和多用同樣的方式
你可以考慮使用一個動作列表或功能
using System;
using System.Collections.Generic;
namespace ReplayConsole
{
class Program
{
private static IList<Action> _actions;
static void Main(string[] args)
{
_actions = new List<Action>
{
() => {
//do thing
},
() => {
//do thing
},
() => {
//do thing
},
() => {
//do thing
},
};
foreach (var action in _actions)
{
action();
}
}
}
您還可以看看Tasks
編輯:
看着那突然出現了,而我在寫我的這個搜索解決方案的答案n與Brook's非常相似
所有這些函數都具有相同的簽名還是會有所不同?你會回憶這些功能相同的論點,還是會改變? – 2011-12-21 01:50:14
@JeffMercado它們會與可變數量的參數和返回類型不同。 – 2011-12-21 01:51:43
也許看看這個問題。 http://stackoverflow.com/questions/377217/c-sharp-delegate-for-two-methods-with-different-parameters它可能不是你想要做的同樣的事情,但它談論運行委託與不同的參數。 – 2011-12-21 02:04:57