My scenario is about developing Math Problems. As a IProblem interface, I thought that the two main properties that it should contain are QuestionText and Response. QuestionText always will be a string, but Response sometimes can be a complex object (a custom Fraction struc) or another datatype like string, decimal, int, etc.
public interface IProblem
{
string QuestionText { get; set; }
object Response { get; }
bool IsComplete();
bool IsCorrect();
}
As you can see, Response is object. I guessed this datatype because all problems by nature have a response. And as it’s an object, I define only get for future errors (casting problems).
My idea is later, in a concrete class to access to this property (Response), without the necessity to cast. Check it out?
public abstract class Problem : IProblem
{
public string QuestionText { get; set;}
public object Response { get; protected set; }
public virtual bool IsComplete()
{
return true;
}
public abstract bool IsCorrect();
}
public class BinaryProblem : Problem
{
public decimal N1 { get; set; }
public decimal N2 { get; set; }
public decimal Response
{
get { return (decimal)base.Response; }
set { base.Response = value; }
}
public override bool IsCorrect()
{
return N1 + N2 == Response;
}
}
And here I’m testing the value.
static void Main(string[] args)
{
BinaryProblem p = new BinaryProblem();
p.N1 = 2;
p.N2 = 4;
p.Response = 6;
IProblem p2 = p;
Console.WriteLine(p2.Response);
Console.WriteLine(p2.IsComplete().ToString());
}
Until now, it works, but I want to know if what I’m doing is correct or a good practice. I’ve seen another people use new operator to do this. Others don’t use the word base.
Is this a good way? Can it be causing future errors? Please, give me a feedback about my design.
EDIT: It’s really necessary to access to the Response in a non-generic interface.
Maybe you’re looking for something like this? Note, I left some things out because they weren’t important to the generic solution part of the problem (like QuestionText). I also left out the base class because it appeared to be nothing more than a pass-through, and an extra, unnecessary layer. This may not be exactly what you’re looking for, but I hope it helps get you there.
First, this is how everything is used:
Edit: Notice how they can all be treated as the non-generic IProblem now.
Edit: Here’s the non-generic interface so many problems can be used in a list and treated the same way:
Here’s the interface:
Edit: Notice that this now implements the non-generic interface.
And here are the classes:
Edit: Notice the new GetResponse() methods.