Domain object ContragentLet's say I have an hierarchy of classes:public class BaseContragent{   public int Id { get; set; }}public class PersonContragent : BaseContragent{   public string FirstName { get; set; }   public string LastName { get; set; }}public class CompanyContragent : BaseContragent{   public string CompanyName { get; set; }}public class BankCompanyContragent : CompanyContragent{   public string BankBic { get; set; }}public class LocalBankCompanyContragent : BankCompanyContragent {   public string NationalBankIdentificator { get; set; }}Actually, this hierarchy has many classes, it has much of business logic, and all fields are taken from business domain logic, so I can't change it just because of inconvenient external service.Contragent- PersonContragent-- PersonWithoutCitizenshipContragent-- CitizenshipContragent--- LocalCitizenshipContragent--- ForeignCitizenshipContragnet- CompanyContragent-- BankCompanyContragent--- LocalBankCompanyContragentetc.Now, external system sends requests to create objectI have a request to create an object from external system, which looks like this:public class CreateRequest{    public int Id { get; set; }    public string Name { get; set; } // default for base, value for subclasses    public int Type { get; set; } // 0 - for Base, 1 for Person, 2 for Company    // many other fields belonging to different types}There is only one type of create request for all types of Contragent, and which one should I use depends on Type value.  In order to isolate my system from this strange external system I have implemented some sort of anti-corruption layer with factories which create objects of this hierarchy:public abstract class BaseContragentFactory {    protected abstract Contragent Create();    protected abstract Fill(Contragent ca, CreateRequest createRequest);    public Base CreateAndFill(CreateRequest createRequest)    {        var ca = Create();        Fill(ca, createRequest);        return ca;    }}public class SimpleContragentFactory : BaseContragentFactory  {    protected virtual Contragent Create()     {        return new Contragent();    }    protected virtual void Fill(Contragent ca, CreateRequest createRequest)    {        ca.Id = createRequest.Id;    }}public class PersonContragentFactory : SimpleContragentFactory {    protected override Contragent Create()    {        return new PersonContragent();    }    protected override void Fill(Contragent ca, CreateRequest createRequest)    {        var pca = ca as PersonContragent;        if (pca == null)            throw new InvalidOperationException(...);        base.Fill(pca, createRequest);        string[] nameParts = createRequest.Name.Split(;); // Firstname;Lastname        pca.FirstName = nameParts[0];        pca.LastName = nameParts[1];    }}public class CompanyContragentFactory : SimpleContragentFactory {    protected override Contragent Create()    {        return new CompanyContragent();    }    protected override void Fill(Contragent ca, CreateRequest createRequest)    {        var bca = ca as CompanyContragent;        if (bca == null)            throw new InvalidOperationException(...);        base.Fill(bca, createRequest);        bca.CompanyName = createRequest.Name;    }}I have such factories for almost every type of Contragent.public void Create(CreateRequest request){    BaseContragentFactory factory;    switch (request.Type)    {        case 0:          factory = new SimpleContragentFactory();          break;        case 1:          factory = new PersonContragentFactory();          break;        case 2:          factory = new CompanyContragentFactory();          break;        default:          throw new InvalidOperationException(...);    }    Contragent ca = factory.CreateAndFill(request);}However, I don't like that this codes has casts, checks and that type-safety is only maintained by a developer.   So, I have two question about improving code type-safety and readability:Question 1: how to combine Create and Fill methods? How to make this class have only one method. The problem that I need to be able to create document only once at the top-inherited class and then call base fill methods.Question 2: is there any way to utilize generics to make these factories more type-safe and accept generic-typed values? May be, s1omething like this:public abstract class BaseContragentFactory<T> where TContragent : Contragent, new(){    protected TContragent Create()     {        return new TContragent();    }    // ...
How to combine these fill and create methods or utilize generics in factory?
c#;object oriented design;inheritance;generics;factory