سؤال

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.

private static void StackOverflowQuestion()
{
    IProblem<int> problem1 = new IntProblem(2, 4);
    problem1.Response = 6;

    IProblem<decimal> problem2 = new DecimalProblem(5, 10);
    problem2.Response = .5M;

    Console.WriteLine("Problem 1 is correct: {0}", problem1.IsCorrect());
    Console.WriteLine("Problem 2 is correct: {0}", problem2.IsCorrect());

    List<IProblem> problems = new List<IProblem>();
    problems.Add(problem1);
    problems.Add(problem2);
    problems.ForEach(problem => Debug.WriteLine(problem.GetResponse()));
}

Edit: Here's the non-generic interface so many problems can be used in a list and treated the same way:

public interface IProblem
{
    object GetResponse();
}

Here's the interface:
Edit: Notice that this now implements the non-generic interface.

public interface IProblem<T> : IProblem
{
    T Response { get; set; }
    bool IsCorrect();
}

And here are the classes:
Edit: Notice the new GetResponse() methods.

public class IntProblem : IProblem<int>
{
    private int _number1 { get; set; }
    private int _number2 { get; set; }

    public int Response { get; set; }

    public IntProblem(int number1, int number2)
    {
        this._number1 = number1;
        this._number2 = number2;
    }

    public bool IsCorrect()
    {
        return this._number1 + this._number2 == Response;
    }

    public object GetResponse()
    {
        return this.Response;
    }
}

public class DecimalProblem : IProblem<decimal>
{
    private decimal _number1 { get; set; }
    private decimal _number2 { get; set; }

    public decimal Response { get; set; }

    public DecimalProblem(decimal number1, decimal number2)
    {
        this._number1 = number1;
        this._number2 = number2;
    }

    public bool IsCorrect()
    {
        return this._number1 / this._number2 == Response;
    }

    public object GetResponse()
    {
        return this.Response;
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top