簡體   English   中英

通用類型,接口

[英]Generic types, Interfaces

我想創建一個通用的通知引擎。 這個想法是有一個單一的核心引擎來處理任何類型的通知。 該引擎將處理通知並處理所有日志記錄,錯誤處理等。

我創建了3個簡單的界面:

public interface INotificationInput
{
    /// <summary>
    /// Friendly Name for logging/tracing usage
    /// </summary>
    string FriendlyName { get; set; }

    string NotificationCode{ get; set; }

    Double Version { get; set; } 
}

public  interface INotificationOutput
{
    /// <summary>
    /// Friendly Name for logging/tracing usage
    /// </summary>
    string FriendlyName { get; }
}

public interface INotificationProvider<out Toutput, Tinput> where Toutput : INotificationOutput where Tinput : INotificationInput
{
    /// <summary>
    /// Friendly Name for logging/tracing usage
    /// </summary>
    string FriendlyName { get; set; }

    /// <summary>
    /// Generates and returns an INotificationOutput from data
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    Toutput GenerateNotificationOutput(Tinput data);
}

因此,INotificationProvider將對INotificationInput進行分塊以創建INotificationOutput。

那可能是發送電子郵件的信息,一條短信(您將其命名),引擎將調用這些方法並發揮調度,記錄日志,處理錯誤等作用。

我實現了這樣的接口:

/// <summary>
    /// INotificationInput represented by a dummy object
    /// </summary>
    public class DummyNotificationInput : INotificationInput
    {
        public string FriendlyName { get; set; }
        public string NotificationCode { get; set; }
        public double Version { get; set; }
    }

public class DummyNotificationOutput : INotificationOutput
{
    public string FriendlyName { get; private set; }
}

public class DummyProvider : INotificationProvider<DummyNotificationOutput, DummyNotificationInput>
{
    public string FriendlyName { get; set; }

    public DummyNotificationOutput GenerateNotificationOutput(DummyNotificationInput data)
    {
        throw new NotImplementedException();
    }
}

現在,我希望我的引擎具有提供程序列表:

 var providersList = new List<INotificationProvider<INotificationOutput, INotificationInput>>();

問題是我無法做到以下幾點:

providersList.Add(new DummyProvider<DummyNotificationOutput, DummyNotificationInput>());

必須有一個解決方案。 我使用錯誤的方法嗎?

INotificationProvider的第二個泛型類型參數不是協變的(在概念級別上),但是您試圖像使用協變一樣使用它。 它實際上是對立的。

INotificationProvider對象列表中,您已將輸入通知定義為INotificationInput 這意味着添加到此列表的對象需要能夠接受任何類型的INotificationInput作為其GenerateNotificationOutput函數的輸入 您試圖添加僅知道如何處理DummyNotificationInput對象的對象。 如果傳遞了其他類型的輸入,它將失敗。

如果希望將提供者添加到該列表中,則提供者需要接受INotificationInput對象,或者該列表需要將所有對象都定義為接受DummyNotificationInput

正如Servy已經回答的那樣,由於providersList的期望,您無法真正做到這一點

考慮到這一點,僅使INotificationProvider為非泛型實際上可能會更簡單:

public interface INotificationProvider
{
    /// <summary>
    /// Friendly Name for logging/tracing usage
    /// </summary>
    string FriendlyName { get; set; }

    /// <summary>
    /// Generates and returns an INotificationOutput from data
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    INotificationOutput GenerateNotificationOutput(INotificationInput data);
}

然后, DummyProvider變為:

public class DummyProvider : INotificationProvider
{
    public string FriendlyName { get; set; }

    public INotificationOutput GenerateNotificationOutput(INotificationInput data)
    {
        throw new NotImplementedException();
    }
}

現在,可能不是您所想的那樣-您期望將DummyNotificationInput實例傳遞給DummyProvider

您只需在您的Provider代碼中輸入check

public class DummyProvider : INotificationProvider
{
    public string FriendlyName { get; set; }

    public INotificationOutput GenerateNotificationOutput(INotificationInput data)
    {
        if (!(data is DummyNotificationInput)) throw new ArgumentException("Invalid type specified", "data");

        return something...;
    }
}

顯然,您浪費了設計時間檢查-但是,如果您確實需要將它們放在協變量列表中,則無法提供具有派生泛型類型參數的實現程序

暫無
暫無

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

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