Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How can you restrict a method parameter based on an enum?

I feel like this is an anti pattern of some sort, but basically I’ve got 2 versions of the same type of repo that have the same type of properties and methods. I played with the idea of both an interface and an abstract class but in neither case can I get around what appears to be unnecessary checks. Here’s the premise (using abstract class):

public abstract class BaseRepository
{
    public abstract RepositoryType RepositoryType { get; } //enum of File or DataBase
    public abstract CreateResult CreateItem (Item item);
    public abstract DeleteResult DeleteItemById(Guid Id);
    public abstract Item GetItem(Guid Id);
}

public class Item
{
    public Guid Id { get; }
    public string Name { get; }
    public ItemType ItemType { get; } //enum of File or DataRecord
    
    //other props...
}

public FileRepository : BaseRepository
{
    public override RepositoryType RepositoryType => RepositoryType.File
    
    public override CreateResult CreateItem(Item item)
    {
        if(item.ItemType != ItemType.File) throw InvalidOperationException("some error message") //problem is here

        //some logic.
    }

    //other overrides....
}

So there’s a basic contract created for a repository via the BaseRepository, which is overridden by the FileRepository. An item basically has the same stuff whether it’s a File item or a DataRecord item (there could arguably be an IItem interface and then 2 separate Items of DataRecord and File rather than an enum but that still doesn’t solve the problem).

The problem is I don’t see how I can pass in an Item with only ItemType File to the FileRepository. It feels like there should be a way of making sure that the FileRepository only receives items of type File and that a check shouldn’t have to be made to ensure it’s got the right type. How can I do this?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Make the repository generic, and introduce types for each type of item. eg:

public abstract class Item
{

}
public class FileItem : Item
{

}
public abstract class Repository<TItem> where TItem : Item
{
    public virtual string RepositoryType => typeof(TItem).Name;
    public abstract CreateResult CreateItem(TItem item);
    public abstract DeleteResult DeleteItemById(Guid Id);
    public abstract Item GetItem(Guid Id);
}

public class FileRepository : Repository<FileItem>
{
    public override CreateResult CreateItem(FileItem item)
    {
        throw new NotImplementedException();
    }

    public override DeleteResult DeleteItemById(Guid Id)
    {
        throw new NotImplementedException();
    }

    public override Item GetItem(Guid Id)
    {
        throw new NotImplementedException();
    }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading