【问题标题】:Configuration of general workflow with generic interfaces使用通用接口配置通用工作流
【发布时间】:2017-05-30 15:29:11
【问题描述】:

我们最近在我们的数据收集程序中偶然发现了一个问题。我们使用通用接口来拥有一个通用的工作流程,该工作流程可以通过配置中的具体实现轻松针对不同的数据输入进行定制。最近对丢失数据错误的修复大致如下所示:

[TestFixture]
internal class GenericsTest
{
    [Test]
    public void Config()
    {
        new Collector(new Search());
    }
    internal class Collector
    {
        public Collector(Clues<Where, What> foo)
        {

        }
    }
    internal interface Clues<T, P>
    {

    }
    internal class Search : Clues<Where, Item>
    {

    }
    internal class Where
    {

    }
    internal class Item : What
    {

    }

    internal interface What
    {

    }

}

配置正在使用特定搜索初始化特定收集器。收集器本身只需要一个带有具体类 Where 和接口 What 作为参数的通用接口。 Search 类应该通过实现具有 Where 类的通用 Clues 接口和自身实现 What 接口的 Item 类来满足这些期望。 相反,Search 的初始化失败,因为它无法在特定实现和一般期望之间建立联系。

Error   CS1503  Argument 1: cannot convert from 'UnitTest.GenericsTest.GenericsTest.Search' to 'UnitTest.GenericsTest.GenericsTest.Clues<UnitTest.GenericsTest.GenericsTest.Where, UnitTest.GenericsTest.GenericsTest.What>'

我们尝试强制转换为所需的类型,但它只是将错误转移到运行时。

一般概念是,工作流尽可能保持通用,配置会处理所有特定要求。需要的具体方法应该在item类中引入,并隐藏在接口后面,避免不必要的混乱。

有没有特定的方法可以在 C# 中编写这样的实现?

【问题讨论】:

  • 欢迎来到 SO!我从您的问题标题中删除了标签。请阅读here为什么。

标签: c# .net generics .net-4.5


【解决方案1】:

您将不得不更改Clues 的定义 并使用covariance

协方差: 使您能够使用比最初指定的更多派生类型

internal interface Clues<T, out P>

编辑

如果您无法更改接口,那么也许您可以更改Collector 类以使用带有约束的泛型:

internal class Collector<TWhere,TWhat> where TWhere:Where where TWhat:What
{
    public Collector(Clues<TWhere, TWhat> foo)
    {

    }
}

那么您必须准确指定您要使用的类型:

public void Config()
{
    new Collector<Where,Item>(new Search());
}

【讨论】:

  • 感谢您的回答。我们一直在摆弄协方差,虽然它适用于上面的简单示例,但它对我们来说打破了一些较低的水平。 Clues 接口本身包含一个使用另一个泛型类型

    的接口的方法。这反过来需要是不变的,但不能,因为接口有一个用于类型

    的 Get 和 Set 方法。

  • 我们当前的解决方法是使用接口而不是实现,并在调用 Get 方法时转换为适当的类型。
  • @Moldavis 我已经用另一个建议编辑了答案 - 希望它会有所帮助
  • 感谢您的努力,但此解决方案会引发与原始问题相同的错误。
  • 它抛出什么错误?这个对我有用。你确定你复制的和我发的一样吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多