1

I currently working on a parser project in C# and have run into problem.

I have an entity folder within my project and within it I have:

Entity
  IEntity.cs (defines a contract for entity classes)
  Contact.cs (main entity class)
  Address.cs (struct for contact class to store address fields)
  EntityType.cs (enum of entities, i.e contact in this case)

My signatures for these types are as follows

public interface IEntity : IComparable

public class Contact : IEntity

public static class EntityFactory
 +public static IEntity GetEntity(string[] fields)

In order to deduct the type for the entity factory, I passed an enum into public static IEntity GetEntity(string[] fields, EntityType.Contact) and used switch statement to defer logic.

I plan to create more classes that will inherit from the IEntity class and that's why I want this to general enough to be able to be extendable.

Whilst the above approach works, it completely ruins the generic structure of my code and that's because I have another folder like so:

Parser
  IParser.cs defines general implementation requirements
  CSVParser.cs concrete type which implements those requirements

IParser.cs

public interface IParser<T> where T : IEntity
{
    T ParseToEntity(string row, EntityType type);
}

CSVParser.cs

    public class CSVParser<T> : IParser<T> where T : IEntity
    {
        public T ParseToEntity(string row, EntityType type)
        {
            string[] fields = FormatContact(row);
            T contact = (T)EntityFactory.GetEntity(type, fields);
            return contact;
        }
}

The issue here is that I don't want to be passing the type when I have T that's constrained to be of IEntity type. I somehow wan't to abstract this away. How do I go about this?

EDIT: Posted an answer, though I still have questions. Why do I need to declare IEntity newbObject instead of T newObject considering i have where T : IEntity constraint?

Likewise, why do I have to cast to (T) the GetEntity method, considering I'm supplying it T generic that is also constrained to IEntity?

6
  • 2
    Get rid of the entity type enum and do (T)EntityFactory.GetEntity(typeof(T), fields) or EntityFactory.GetEntity<T>(fields) and switch on the actual type. Aug 22, 2021 at 20:55
  • 4
    Factories return results that satisfy a shared, known interface. “Anything” is a poor target for a factory.
    – Telastyn
    Aug 22, 2021 at 21:01
  • @FilipMilovanović Hi, could you elaborate on how I'd go about switching on the actual type then? I tried the switching on typeof(T) and capturing the case typeof(Contact) but switch allows only constant expressions. Should I use if statement instead?
    – Vocaloidas
    Aug 23, 2021 at 5:53
  • Figured it out with pattern matching in switch statement. Thank you both.
    – Vocaloidas
    Aug 23, 2021 at 7:22
  • 1
    @Vocaloidas Since you figured it out, you might want to answer your own question so others can benefit from what you've learned. Aug 23, 2021 at 14:45

1 Answer 1

2

The solution was to use switch pattern matching like so

public static IEntity GetEntity<T>(string[] fields)
where T : IEntity
{
    IEntity newObject;
    switch(type(T))
    {
        case Type typeContact when typeContact == typeof(Contact)
        //Do the object instantiation
    }

}

Then when I wanna create an object elsewhere I can just

T contact = (T)EntityFactory.GetEntity<T>(fields);
1
  • 1
    Since you're using generics, you can change the return type to T, as in T GetEntity<T>(string[] fields), to avoid having to type cast, since you've constrained it to derivatives of IEntity (where T : IEntity). Aug 25, 2021 at 2:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.