C# Factory Pattern – How to Implement Without Argument for Object Type?

cdesign-patternsfactory-patterngenericsobject-oriented

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?

Best Answer

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);