Mauro Luque Mauro Luque - 27 days ago 7
C# Question

C# Instantiate derived class from base constructor based on parameter type

I have the following model (simplified):

Database models:

public abstract class Question
{
public int Id { get; set; }
public string Text { get; set; }
}

public class QuestionA : Question
{
public bool OptionA { get; set; }
}

public class QuestionB : Question
{
public int OptionB { get; set; }
}


View models:

public abstract class QuestionModel
{
public string Text { get; set; }

protected QuestionModel(Question question)
{
Text = question.Text;
}
}

public class QuestionAModel : QuestionModel
{
public bool OptionA { get; set; }

public QuestionAModel(QuestionA questionA) : base(questionA)
{
OptionA = questionA.OptionA;
}
}

public class QuestionBModel : QuestionModel
{
public int OptionB { get; set; }

public QuestionBModel(QuestionB questionB) : base(questionB)
{
OptionB = questionB.OptionB;
}
}


Basically is to map database entities to view models, and I have for example, this controller:

public class SomeController : Controller
{
public JsonResult Get()
{
// Simulating questions from the database
var questions = new List<Question>
{
new QuestionA { Id = 1, OptionA = true, Text = "fooA" },
new QuestionB { Id = 1, OptionB = 1, Text = "fooB" }
};

var model = questions.Select(q => new QuestionModel(q)).ToList();

return Json(model);
}
}


This obiously don't compile because the
new QuestionModel(q)


I know the type of every question from database, how I can create derived question models of the each question entity?

Thanks to all!!

Answer

Instead of calling the constructor, create a factory class that will provide the correct implementation based on the type of the object that you have to create.

Notice that you will have to materialize your objects from the DB before calling the factory:

var model = questions.ToList().Select(q => QuestionFactory.CreateQuestion(q));