簡體   English   中英

C#如何在通用方法中使用自定義擴展

[英]c# How to use custom extensions in generic method

我有一些復制的代碼,因此正在尋找一種通用方法。 我有一個常用的命名擴展方法,我想在該方法中使用。 通常,如果它不是擴展方法,我將創建一個接口,通過該接口限制通用參數類,然后可以使用該通用方法。 但這不適用於擴展方法。

這是我的通用方法:

public ActionConfirmation<string> CreateUpdateEntity<TExternalEntity, TQuickbooksEntity>(TExternalEntity entity, CompanyPreferencesFinancialsSystemCommon preferences)
    where TExternalEntity : class, OTIS.Domain.IEntity, IFinancials, IExternalMapper<TExternalEntity, TQuickbooksEntity>, new()
    where TQuickbooksEntity : class, Intuit.Ipp.Data.IEntity, new()
{
    return CreateUpdateQuickBooksEntity<TQuickbooksEntity>(
        entity.ToQuickBooksEntity(preferences),
        x => x.Id == entity.FinancialsId,
        entity.FinancialsId);
}

嘗試界面

public interface IExternalMapper<TExternalEntity, TQuickbooksEntity>
    where TExternalEntity : class, OTIS.Domain.IEntity, new()
    where TQuickbooksEntity : class, Intuit.Ipp.Data.IEntity, new()
{
    static TQuickbooksEntity ToQuickBooksEntity<TExternalEntity>(this TExternalEntity externalEntity, CompanyPreferencesFinancialsSystemCommon preferences);
}

這會產生錯誤:

Extension method must be defined in a non-generic static class

和這個

public static class VendorExtensions : IExternalMapper<OTIS.Domain.InventoryMgmt.Vendor, Intuit.Ipp.Data.Vendor>
    {
        public static Intuit.Ipp.Data.Vendor ToQuickbooksEntity(this OTIS.Domain.InventoryMgmt.Vendor importedVendor)

Static classes cannot implement interfaces結果Static classes cannot implement interfaces

我了解為什么這行不通。 但是不知道如何重新構造代碼以支持在通用方法中使用擴展方法的要求。

他們幾乎總結為

擴展方法必須在非通用靜態類中定義

只需在靜態類中定義擴展方法

public static class MapperExtensions    
{
     public static TQuickbooksEntity ToQuickBooksEntity<TExternalEntity>(this TExternalEntity externalEntity, CompanyPreferencesFinancialsSystemCommon preferences) 
                        where TExternalEntity : class, OTIS.Domain.IEntity, new()
                        where TQuickbooksEntity : class, Intuit.Ipp.Data.IEntity, new()
     {    
          //return do implimentation    
     }
}

然后,當您要映射時,請擺脫接口,直接使用擴展名。

using namespacetoextensions;

public ActionConfirmation<string> CreateUpdateEntity<TExternalEntity, TQuickbooksEntity>(TExternalEntity entity, CompanyPreferencesFinancialsSystemCommon preferences)
    where TExternalEntity : class, OTIS.Domain.IEntity, IFinancials, new()
    where TQuickbooksEntity : class, Intuit.Ipp.Data.IEntity, new()
{
    return CreateUpdateQuickBooksEntity<TQuickbooksEntity>(
        entity.ToQuickBooksEntity(preferences),
        x => x.Id == entity.FinancialsId,
        entity.FinancialsId);
}

為了澄清起見,您正在嘗試以某種C#功能無法使用的方式使用它們。

靜態類是密封的,因此無法繼承。 它們不能從Object以外的任何類繼承。

這意味着使用擴展方法實現接口非常簡單,無法正常工作。

因此,您有兩種選擇,要么刪除接口,要么僅直接使用擴展方法,如下所示:

public static class Extensions
{
    public static TExternalEntity ToQuickBooksEntity<TExternalEntity, TQuickbooksEntity>(this TQuickbooksEntity externalEntity)
        where TExternalEntity : class, OTIS.Domain.IEntity, new()
        where TQuickbooksEntity : class, Intuit.Ipp.Data.IEntity, new()
    {
        throw new NotImplementedException();
    }
}

或者,您不能使用擴展方法,而應使用帶有隱含功能的接口。 (我將直接演示此示例)。

如果對於不同類型的TExternalEntity,ToQuickBooksEntity的實現細節明顯不同,則可能不應該將其作為擴展方法。 它應該是適當類上的實例方法,以便您可以利用多態性。

如果實現細節不太依賴於TExternalEntity的類型,而您想將其保留為擴展方法,則沒有理由在接口上對其進行定義。 相反,使其成為靜態類的方法。 您需要的任何泛型類型約束都可以是方法本身的泛型約束,您不需要類是泛型的。

擴展方法必須在非通用靜態類中定義

錯誤不是很清楚嗎? 擴展方法應該是靜態方法,應該在非通用靜態類中對其進行定義才能起作用。 靜態類也必須繼承自System.Object並且也不能實現任何interface

在靜態類中, interface實現是非法的,因為靜態類不能具有實例成員,但是沒有實例成員,接口就沒有意義。

暫無
暫無

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

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