簡體   English   中英

結合通用方法和重載

[英]Combining generic methods and overloads

我有以下方法:

public void Set<T>(IEnumerable<T> records)
{
     foreach (var record in records)
     {
        Set(record);
     }
 }

我希望調用以下任一Set方法,具體取決於T

    public void Set(RecordType1 record)
    {
        // Some RecordType1 logic
    }

    public void Set(RecordType2 record)
    {
        // Some logic applicable to RecordType2 only
    }

希望您可以看到我正在嘗試允許在運行時調用哪個Set方法。 這“不起作用”(即不會編譯,因為它期望RecordType1 )。

在將記錄發送到Set方法之前,如何在不測試類型的情況下保留這種結構?

為什么不創建接口( IRecordType ),允許RecordType1RecordType2繼承它,然后將每個Set方法的主邏輯移動到接口。

public interface IRecordType
{
    void Set(...);
}
public void Set(IEnumerable<IRecordType> records)
{
    foreach (var record in records)
    {
        record.Set(...);
    }
}

這是一種更易於維護的解決方案。 它還允許更好的多態性。

編輯:要查看的資源: https//msdn.microsoft.com/en-us/library/3b5b8ezk%28v=vs.90%29.aspx

此外,小側邊欄:使用interface您不僅可以共享某些方法,還可以共享屬性和事件。 如果RecordType1RecordType2共享幾個公共屬性,則可以將這些屬性添加到interface ,然后在以前需要的任何地方使用IRecordType來區分這兩個屬性,方法或事件。 同樣地,內部的任何的那些屬性,方法和事件代碼允許依靠其他屬性,方法,事件或特定於對象本身的字段。 這是面向對象語言( C# )和多態的目的。

編輯:作為評論中討論的結果,我還想添加有關使用OOP方法( interfaceabstract classclass )和StriplingWarrior建議的dynamic方法之間決策的更多信息:

如果您無法訪問RecordType1RecordType2的實際實現細節,或者您無法更改應用程序的設計(由於阻礙了對Set(RecordType1)Set(RecordType2)方法的依賴,您可能會發現采用dynamic方法更有成效。還有其他選擇,我們可能沒有想到 - 你總是可以給它們一個去。 dynamic方法的缺點是它需要.NET 4.0。

此外,還有更多注意事項:如果您確實可以訪問RecordType1RecordType2實現細節,但是無法更改Set(RecordType1)Set(RecordType2) ,只要定義,您可以隨時修改它們的主體:

public void Set(RecordType1 record)
{
    record.Set(...);
}

public void Set(RecordType2 record)
{
    record.Set(...);
}

這樣可以保留整個應用程序結構,同時還可以減少代碼維護並允許多態性。

如果你是積極的,給定的集合中的每個項目將匹配方法簽名,你可以投的值作為dynamic ,讓運行弄清楚如何將其綁定到:

 foreach (var record in records)
 {
    Set((dynamic)record);
 }

但是,這很容易出錯 ,我建議你仔細看看你真正要完成的事情。 最有可能是一種更好的模式來滿足您的需求。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM