2013-09-30 52 views
3

我有以下的抽象类和接口:替换基类的具体实现C#

public interface ITypedEntity{ 
    TypedEntity Type { get; set; } 
} 

public abstract class TypedEntity:INamedEntity{ 
    public abstract int Id{get;set;} 
    public abstract string Name { get; set; } 
} 

但是当我试图创建一个实现ITypedEntity并具有TypedEntity的concrecte实现一类我得到以下错误

Magazine does not implement interface member ITypedEntity.Type. Magazine.Type cannot implement 'ITypedEntity.Type' because it does not have the matching return type of 'TypedEntity' 

我concrecte实现的代码如下

public class Magazine:INamedEntity,ITypedEntity 
{ 
    public int Id {get;set;} 
    [MaxLength(250)] 
    public string Name {get;set;} 
    public MagazineType Type { get; set; } 
} 
public class MagazineType : TypedEntity 
{ 
    override public int Id { get; set; } 
    override public string Name { get; set; } 
} 

我想我明白发生了什么,但我不知道为什么,因为MagazineType是一个TypedEntity。

谢谢。

更新1 我不得不提一下,我想利用这个班,EF CodeFirst,我想有一个不同的表中的每个实现ITypedEntity类的。

+0

MagazineType是TypedEntity但TypedEntity我没有MagazineType。也许你可以像'ITypedEntity Type {get;组; }' –

+1

但是,存储在“ITypedEntity”类型的变量中的引用“杂志”的代码可能会尝试将*不是'MagazineType'的内容存储到'Type'属性中。 –

+0

将'Magazine.Type'的返回类型更改为'EntityType'。它仍然可以是'MagazineType'的一个实例,但签名必须匹配才能满足接口实现的要求。 – Jodrell

回答

7

这不要紧,MagazineType是一个TypedEntity。想象一下你还有另外一个ITypedEntity的实现,NewspaperType。在ITypedEntity接口的合同规定,你必须能够做到:

ITypedEntity magazine = new Magazine(); 
magazine.Type = new NewspaperType(); 

然而,这违背了你的代码,其中Magazine.Type不接受ITypedEntity其他亚型。 (我相信你的代码将是有效的,如果属性只有一个getter虽然)。

一个解决办法是使用泛型:

interface ITypedEntity<TType> where TType : TypedEntity 
{ 
    TType Type { get; set; } 
} 

class Magazine : ITypedEntity<MagazineType> 
{ 
    // ... 
} 
7

您需要将MagazineType改变TypedEntity

public class Magazine:INamedEntity,ITypedEntity 
{ 
public int Id {get;set;} 
[MaxLength(250)] 
public string Name {get;set;} 
public TypedEntity Type { get; set; } 
} 

但是当你创建杂志的对象,那么你可以派生类型分配给它

var magazine = new Magazine { Type = new MagazineType() } 
+0

我知道这样做,但问题是,这是我打算与EF CodeFirst一起使用的一些模型,而且我不确定这将如何工作,因为我想为TypedEntity的每个类Concrect实现有不同的表 – trebor

1

要做到这一点,你必须添加ITypedEntity.Typeexplicit implementation

public class Magazine:INamedEntity,ITypedEntity 
{ 
    public int Id {get;set;} 
    [MaxLength(250)] 
    public string Name {get;set;} 
    public MagazineType Type { get; set; } 

    TypedEntity ITypedEntity.Type 
    { 
     get 
     { 
      return this.Type; 
     } 
     set 
     { 
      this.Type = value as MagazineType; // or throw an exception if value 
               // is not a MagazineType 
     } 
    } 
} 

用法:

Magazine mag = new Magazine(); 
mag.Type     \\ points to `public MagazineType Type { get; set; }` 
((ITypedEntity)mag).Type \\ point to `TypedEntity ITypedEntity.Type`