2014-07-16 207 views
1

为什么我不能这样做?使用实现所需返回类型的返回类型实现接口

IHasOperatingSystem { 
IOperatingSystem OperatingSystem { get; } 
} 

Computer<T> : IHasOperatingSystem where T : IOperatingSystem { 
public T OperatingSystem { get; } 
} 

它告诉我,该类型应该是IOperatingSystem,但是如果T实现IOperatingSystem,应该不够吗?

此外,我意识到这个问题的标题可能有点混淆,但我想不出一个更好的方式来描述它。

回答

6

它告诉我,该类型应该是IOperatingSystem,但是如果T实现IOperatingSystem,应该不够吗?

不,这只是C#的工作方式。为了实现接口或覆盖方法,参数类型和返回类型必须与完全匹配。从C#5规范的章节13.4.4:

对于接口映射的目的,类部件A时的接口部件B相匹配:

  • A和B是方法,以及名称,类型和形式参数列表A和B是相同的。
  • ...

(这里的 “类型” 应读为 “返回类型”)

现在你可以让你的IHasOperatingSystem型通用的,当然:

public interface IHasOperatingSystem<T> where T : IOperatingSystem 
{ 
    T OperatingSystem { get; } 
} 

public class Computer<T> : IHasOperatingSystem<T> where T : IOperatingSystem 
{ 
    public T OperatingSystem { get { ... } } 
} 

或者您也可以使用Computer<T>类中的显式接口实现:

public interface IHasOperatingSystem 
{ 
    IOperatingSystem OperatingSystem { get; } 
} 

public class Computer<T> : IHasOperatingSystem where T : IOperatingSystem 
{ 
    // Explicit interface implementation... 
    IHasOperatingSystem.OperatingSystem IOperatingSystem 
    { 
     // Delegate to the public property 
     get { return OperatingSystem; } 
    } 

    public T OperatingSystem { get { ... } }; 
} 
+0

感谢。我喜欢第二种方法。 IHasOperatingSystem接口的使用非常广泛,因此使其通用会比我想要的更具有侵入性。尽管如此,我仍然有点模糊。会允许这个问题产生(即永远不会被允许),还是仅仅因为目前设计的东西而不允许? – Eric

2

如果T实现IOperatingSystem,应该不够吗?

即使它在其他语言(斯卡拉,我认为)可能是足够的,在C#中,它不是。返回类型是不变的(除了委托返回类型,which are covariant)。

一种用于这些情况下常见的解决方法是使用泛型,因为这样的:

IHasOperatingSystem<T> where T: IOperatingSystem 
{ 
    T OperatingSystem { get; } 
} 

Computer<T> : IHasOperatingSystem <T> where T : IOperatingSystem 
{ 
    public T OperatingSystem { get; } 
} 
相关问题