2013-10-15 15 views
1

背景:代表返回數據依賴的呼叫者的

  • 我具有相同的類(X)的1個... *對象。
  • 對象被賦予一個爲其獲取數據的委託。
  • 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,但我不明白它是如何使用的,我甚至不確定它適用於這種情況嗎?

任何建議如何處理這個?

+0

不太清楚你在這裏要做什麼。你的問題到底是什麼? –

回答

1

你可以用代碼在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 
    }; 
} 

如果你需要的XgetRows的情況下,你可以這樣做:

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

由於itertator塊(又名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); 
    } 
} 
+0

這似乎是一種有效的方法。不過,我需要更多的指導。 Visual Studio抱怨收益聲明。 「產量聲明不能在lambda表達式中使用」我現在感覺如此愚蠢 – Anders

+0

@Anders啊,是的,'yield'在匿名函數中不起作用。如果你真的需要「收益」來工作,我會更新我的答案。 – sloth

+0

@Anders更新了我的答案 – sloth

0

如果您可以控制暴露委託的類,那麼只需將委託更改爲接受調用者的參數即可。否則你運氣不好。

無論如何,這種體系結構充其量是有問題的。

+0

我可以擴展它。是否有可能重載委託簽名,就像其他任何方法一樣:'public delegate IEnumerable GetRowsHandler(List data);'?至少Visual Studio似乎很滿意。不過,我不知道如何在使用此方法時向委託提供參數。 – Anders