【问题标题】:Concrete class which inherites a generic interface继承通用接口的具体类
【发布时间】:2019-01-05 18:42:23
【问题描述】:

我想要一个通用接口,它的属性用作派生类的 Id 属性。

我写的界面如下:

interface IEntity<T>
{
    T Id { get; set; }
}

派生类可以像下面这样使用它:

public class Employee : IEntity<int>
{
    // don't need to define Id property
    // public int Id { get; set; }
}

public class Document : IEntity<string> { ... }

不幸的是,编译器会提示这个错误:

'Employee' 没有实现接口成员'IEntity.Id'

我做错了什么?谢谢。

编辑: 虽然接受的答案解决了问题,但@dbc cmets 帮助我实现了我的目标,如果我将interface IEntity 更改为abstract class IEntity,则不需要在派生类中实现 Id 属性。

【问题讨论】:

标签: c# generics interface


【解决方案1】:

您混淆了继承和接口实现。

当一个接口继承另一个接口时,成员都是继承的,你不用重复了:

interface IEntity<T>
{
    T Id { get; set; }     // necessary code for 'get' and 'set' not present (yet)
}
interface IEmployee : IEntity<int>
{
    // don't need to repeat Id property
    // it is inherited
}

类似地,当一个类继承另一个类时:

class Entity<T>
{
    public T Id { get; set; }     // automatic code for 'get' and 'set' exists here
}
class Employee : Entity<int>
{
    // don't need to repeat Id property
    // it is inherited
}

如果您想确保只实例化派生类,则可以将基类设为abstract

但是当一个类(或结构)实现和接口时,接口的每个成员都必须以某种方式实现。通常由该类或结构的公共成员。 (该公共成员可能从基类继承!)或者,偶尔,通过 显式 接口实现。

接口没有主体,只有签名。例如,Id 属性的 getset 访问器必须有一些主体才有意义。当您在接口中写入T Id { get; set; } 时,没有访问器的主体。但是当你在一个类(或结构体)中写T Id { get; set; },并且没有abstractextern修饰符时,分号有另一种含义;然后编译器同时自动生成必要的访问器主体(并自动生成访问器使用的字段)。

【讨论】:

    【解决方案2】:

    和接口一样,所有方法都必须实现!

    属性只不过是方法,在接口中定义时必须实现:int Id { get; set; }

    【讨论】:

    【解决方案3】:

    您需要为每个类实现接口 - 就像前面提到的:

    interface IEntity<T>
    {
        T Id { get; set; }
    }
    
    public class Employee : IEntity<int>
    {
        public int Id { get; set; }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-19
      • 1970-01-01
      • 1970-01-01
      • 2015-10-03
      • 1970-01-01
      • 2016-08-09
      • 2016-07-10
      相关资源
      最近更新 更多