委托返回依赖于调用方的数据

本文关键字:数据 调用 依赖于 返回 | 更新日期: 2023-09-27 18:35:37

背景:

  • 我有 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的一些帖子建议进行委托。可以使用调用者,但我不明白它是如何使用的,我什至不确定它是否适用于这种情况?

有什么建议如何处理吗?

委托返回依赖于调用方的数据

您可以使用闭包将getRows()中的代码包装到接受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
    };
}

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

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
    };
}

由于迭代器块(又名 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);
    }
}

如果您可以控制公开委托的类,则只需更改委托以接受调用方的参数即可。否则你就不走运了。

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