实现具有实现所需返回类型的返回类型的接口

时间:2014-07-16 19:46:56

标签: c# .net generics

为什么我不能这样做?

IHasOperatingSystem {
IOperatingSystem OperatingSystem { get; }
} 

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

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

另外,我意识到这个问题的标题可能有点令人困惑,但我想不出更好的方式来表达它。

2 个答案:

答案 0 :(得分:6)

  

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

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

  

出于接口映射的目的,类成员A在以下情况下匹配接口成员B:

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

(此处“type”应读作“return type”。)

现在,您可以将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 { ... } };
}

答案 1 :(得分:2)

  

如果T实现IOperatingSystem,那不够吗?

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

针对这些情况的常见解决方法是使用泛型,如下:

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

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