从方法返回通用接口和子实现

时间:2009-11-17 22:50:06

标签: c#

我有一个通用接口,其中类型约束是一个抽象基类。

因此实现可能是不同的实现。

虽然这很好,但是当我尝试从设置为返回接口的方法(例如ITest)返回具体实现(例如ITestImplementation)时,这会在Visual Studio中引发有关隐式转换的各种编译时错误。 / p>

代码:

ITest<Control>
{
  void Execute();
}

我在各个地方使用此界面并返回上述方法。也许我应该使用泛型类占位符。

这不可能吗?

由于

3 个答案:

答案 0 :(得分:3)

你想要的是通用差异;具体来说,您希望Interface1具有协变性。

C#3不支持通用差异。它将在C#4中。如果您说

,您的代码将起作用
interface Interface1<out T>

然而,您需要只使用T,以便您想要的界面转换可证明安全。

考虑一个例子,看看我的意思是不合法的。假设您有一个实现IList<Mammal>的对象。它实际上是一份哺乳动物名单。您希望将其转换为IList<Animal>,并确定“哺乳动物列表可用作动物列表”。但是你可以将一条蛇插入一个动物名单中,这样就会试图将一条蛇放入一系列哺乳动物中,然后撞到它们。列表不能安全协变。

如果您可以向编译器证明您的界面对协方差是安全的,那么C#4将允许您这样做。我将在接下来的几周内详细描述我博客上的安全要求。

答案 1 :(得分:1)

不是100%肯定你拍摄的是什么,而是查看协方差和逆变的讨论,看看你的场景现在是否可能,或者你是否需要等待c#4.0。

https://stackoverflow.com/questions/1078423/c-is-variance-covariance-contravariance-another-word-for-polymorphism

答案 2 :(得分:0)

抱歉,代码正在运行,但我在家重新创建了错误:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ArtOfTest.WebAii.Controls.HtmlControls;

namespace iCrawler.Code
{
    interface Interface1<T> where T : HtmlControl
    { // May use T for future methods which will be generic in nature eg work with a generic collection of instances of T (not depicted in the method signature below)
        void DoStuff();
    }

    class Child1 : Interface1<ArtOfTest.WebAii.Controls.HtmlControls.HtmlAnchor>
    {
        public void DoStuff()
        {
            throw new NotImplementedException();
        }
    }

    class Test
    {

        public Interface1<HtmlControl> ReturnExperiment()
        {
            Child1 child1 = new Child1();
            return child1;
        }

    }
}

在“return child1”行中,我收到以下错误:

Error   1   Cannot implicitly convert type 'iCrawler.Code.Child1' to 'iCrawler.Code.Interface1<ArtOfTest.WebAii.Controls.HtmlControls.HtmlControl>'. An explicit conversion exists (are you missing a cast?)    C:\Projects\Current\iCrawler\iCrawler\iCrawler\Code\Interface1.cs   28  20  iCrawler

另外,我很确定返回Child1(其中Child1是不是变量的类型)是完全合法的吗?

由于