简体   繁体   English

用具体实现替换基类C#

[英]Replace a base class with a concrete implementation C#

I have the following abstract class and interface: 我有以下抽象类和接口:

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

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

But when i try to create a class that implements ITypedEntity and has a concrecte implementation of TypedEntity i get the following error 但是当我尝试创建一个实现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'

The code for my concrecte implementation is below 我的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; }
}

I think i understand what is happening but i don't know why because MagazineType is a TypedEntity. 我想我明白发生了什么,但我不知道为什么因为MagazineType是TypedEntity。

Thanks. 谢谢。

Update 1 I have to mention that i want to use this classes with EF CodeFirst and i want to have a different table for each of the classes that implement ITypedEntity. 更新1我必须提到我想在EF CodeFirst中使用这个类,并且我希望为实现ITypedEntity的每个类都有一个不同的表。

you need to change the MagazineType to TypedEntity 您需要将MagazineType更改为TypedEntity

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

but when you create object of Magazine then you can assign a derived type to it 但是当你创建杂志的对象时,你可以为它分配派生类型

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

It doesn't matter that MagazineType is a TypedEntity . MagazineTypeTypedEntity并不重要。 Imagine you have another ITypedEntity implementation, NewspaperType . 想象一下,你有另一个ITypedEntity实现, NewspaperType The contract of the ITypedEntity interface states you must be able to do: ITypedEntity接口的合同声明您必须能够:

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

However this contradicts your code, in which Magazine.Type doesn't accept other subtypes of ITypedEntity . 但是,这与您的代码相矛盾,其中Magazine.Type不接受ITypedEntity其他子类型。 (I believe your code would be valid if the property only had a getter though.) (我相信如果该物业只有一个吸气剂,你的代码将是有效的。)

A solution would be using generics: 解决方案是使用泛型:

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

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

To achieve this you have to add an explicit implementation of ITypedEntity.Type : 要实现此目的,您必须添加ITypedEntity.Typeexplicit实现

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 
        }
    }
}

Usage: 用法:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM