1

背景:

  • 我有 1...* 同一类 (X) 的对象。
  • 对象被赋予一个为其获取数据的委托。
  • X 类的所有对象都使用相同的委托。
  • X 类的每个对象都需要一组不同的数据。
  • 我正在使用的 SDK 已将委托声明为没有参数。

我不知何故需要检查哪个对象正在调用委托并据此行事。

代码部分 1:以下部分显示了创建 X 类对象的片段。正如评论所指出的,getRows 被定义为“回调”

public void getTables() {
    foreach(X currentTable in mapper.getTables()) {
        MTables.Add(new X {
            TableName = currentTable.getName(),
            GetRows = getRows,  //This is the delegate
            Fields = Fields.ToArray()
        });
    }
}

代码部分 2: X 类声明委托如下:

public X.GetRowsHandler GetRows { get; set; }
public delegate IEnumerable<QvxDataRow> GetRowsHandler();

代码部分 3:这是函数“getRows”的伪代码

private IEnumerable<QvxDataRow> getRows() {         
    // foreach row belonging to calling instance of class X
        //yield return row;  
}

第 3 节和第 1 节在同一个类中声明,使用 SDK 示例。

在过去的 5 个小时里,我一直在寻找解决方案,但我无法绕过代表。以前关于 SO 的一些帖子建议可以使用 delegare.Caller ,但我不明白它是如何使用的,我什至不确定它是否适用于这种情况?

任何建议如何处理这个问题?

4

2 回答 2

1

您可以使用闭包将代码包装getRows()到接受 a 的方法中:parameter

public void getTables() {
    foreach(X currentTable in mapper.getTables()) {
        MTables.Add(new X {
            TableName = currentTable.getName(),
            GetRows = getRows(currentTable.getName()), 
            Fields = Fields.ToArray()
        });
    }
}

// this method now returns another method that matches GetRowsHandler 
private GetRowsHandler getRows(string tablename) {         
    // this lambda method uses the tablename parameter
    return () =>
    {
        // something with foreach row in table tablename
    };
}

如果您需要Xin的实例getRows,您可以执行以下操作:

public void getTables() {
    foreach(X currentTable in mapper.getTables()) {
        var x = new X {
            TableName = currentTable.getName(),
            Fields = Fields.ToArray()
        });
        x.GetRows = getRows(x), 
        MTables.Add(x);
    }
}

private GetRowsHandler getRows(X instance) {         
    return () =>
    {
        // something with instance
    };
}

由于迭代器块(aka yield)在匿名函数中不起作用,您可以创建一个类来捕获参数而不是使用闭包:

class GetRowsWrapper
{
    X _instance;

    public Something(X instance)
    {
        _instance = instance;
    }

    public IEnumerable<QvxDataRow> getRows()
    {
        // do something with _instance
        yield return yourstuff;
    }
}

public void getTables() {
    foreach(X currentTable in mapper.getTables()) {
        var x = new X {
        TableName = currentTable.getName(),
        Fields = Fields.ToArray()
        });
        // lambda to wrap getRows into a GetRowsHandler
        x.GetRows = () => new GetRowsWrapper(x).getRows();
        MTables.Add(x);
    }
}
于 2013-10-15T11:37:26.910 回答
0

如果您可以控制暴露委托的类,那么只需更改委托以接受调用者的参数。否则你就不走运了。

无论如何,这种架构充其量是值得怀疑的。

于 2013-10-15T11:36:55.313 回答