繁体   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