Bobby Tables
Bobby Tables

Reputation: 3013

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

 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

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.

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.

Upvotes: 3

Views: 269

Answers (3)

manji
manji

Reputation: 47978

To achieve this you have to add an explicit implementation of ITypedEntity.Type:

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`

Upvotes: 1

millimoose
millimoose

Reputation: 39970

It doesn't matter that MagazineType is a TypedEntity. Imagine you have another ITypedEntity implementation, NewspaperType. The contract of the ITypedEntity interface states you must be able to do:

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

However this contradicts your code, in which Magazine.Type doesn't accept other subtypes of 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>
{
    // ...
}

Upvotes: 7

TalentTuner
TalentTuner

Reputation: 17556

you need to change the MagazineType to 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() }

Upvotes: 7

Related Questions