C#:将参数传递给回调

时间:2010-07-06 09:15:28

标签: c# silverlight callback

我有一个相当通用的类(Record),我已经添加了一个回调处理程序,所以我可以执行以下操作。

record.Save(AfterSaveMethod);

还返回创建的记录的标识号。我现在的问题是我在循环中有这个嵌套的保存例程,我需要使用/传递i变量!

for (int i; i < count ;i++)
{
    record.Save(AfterSaveMethod2) //but I need to pass i through as well
}  

我在这做什么?

A \重写save方法并将其包含在此类(yuk)中,

B \有一个重载的保存选项,它将一个对象作为参数,因此我可以将它传递给我的记录类,然后将其与标识号合并。返回身份编号和传递对象中包含的任何额外内容(嗯,听起来有点乱),

C \有更性感的选择吗?

3 个答案:

答案 0 :(得分:8)

这是匿名方法或lambda表达式非常方便的地方:)

试试这个(假设C#3):

for (int i = 0; i < count; i++)
{
    int index = i;
    record.Save(id => AfterSaveMethod2(id, index));
}

请注意,此处的lambda表达式是捕获index,而不是i - 这是为了避免closing over the loop variable中固有的问题。

答案 1 :(得分:2)

您还可以创建一个(线程静态)上下文对象,它存储您的“状态”(在本例中为索引变量值),您可以使用静态属性(例如MyContext.Current)来访问该对象。取决于背景的复杂性......

WCF使用OperationContext.Current,ASP.NET,TransactionScope等。

如果上下文比你的上下文复杂一点,并且你不想污染几种方法的签名,我认为这个模型非常简洁。

使用:

// init context
MyContext.Current = new MyContext();
for (var idx = 0; idx < 99; idx++) {
    MyContext.Current.Idx = idx;
    record.Save(AfterSaveMethod);        

}
// uninitialize context
MyContext.Current = null;

(非常简单的样本)

如果上下文为[ThreadStatic],您可能会有多个不会相互影响的并发呼叫

答案 2 :(得分:0)

    class SexierSaveMethod
    {
        public Int32 Index { get; set; }

        public SexierSaveMethod(Int32 i)
        {
            Index = i;
        }

        public void AfterSaveMethod()
        { 
            // Use i here
        }
    }

    record.Save(new SexierSaveMethod(i).AfterSaveMethod);