2012-04-19 1 views
8

Мой сценарий посвящен разработке математических задач. Как интерфейс IProblem, я думал, что два основных свойства, которые он должен содержать, - это QuestionText и Response. QuestionText всегда будет строка, но Response иногда может быть сложный объект (пользовательский Fraction STRUC) или другой тип данных, как строки, десятичной, междунар и т.д.Как инкапсулировать свойство в базовом классе?

public interface IProblem 
    { 
     string QuestionText { get; set; } 
     object Response { get; } 

     bool IsComplete(); 
     bool IsCorrect(); 
    } 

Как вы можете видеть, Response является объектом. Я догадался, что этот тип данных, потому что все проблемы по природе имеют ответ. И поскольку это объект, я определяю, как получить только будущие ошибки (проблемы с литьем).

Моя идея позже, в конкретном классе для доступа к этому объекту (Response), без необходимости бросать. Проверьте это?

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

И здесь я проверяю значение.

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

До сих пор это работает, но я хочу знать, правильно ли я выполняю то, что я делаю, или хорошая практика. Я видел, как другие люди используют new оператора для этого. Другие не используют слово base.

Это хороший способ? Может ли это быть причиной будущих ошибок? Пожалуйста, дайте мне отзыв о моем дизайне.

РЕДАКТИРОВАТЬ: действительно необходимо получить доступ к ответу в не-универсальном интерфейсе.

+3

Лично я использовал бы либо Generics, либо интерфейс IResponse по объекту. Используя объект, Response может буквально быть чем угодно, включая StringBuilder и Int32 или даже WebRequest. Используя интерфейс или Generics, вы будете иметь гораздо более жесткий контроль над тем, как выполняются ответы. – ctorx

+0

Да, и; «Ответ» всегда является числовым значением?Если это тогда, то просто используйте наиболее подходящий численный тип, т. Е. 'Double' или' decimal', в зависимости от того, что подходит. –

+0

Согласитесь с @ctorx, Generics решит проблему намного чище, в то время как мне нравится скрывать методы/свойства класса, в этом случае вам нужно будет иметь имя diff для каждого типа результата и только показать результат, который вы хотите для типа интерфейс –

ответ

4

Возможно, вы ищете что-то вроде этого? Заметьте, я оставил некоторые вещи, потому что они не были важны для частичного решения проблемы (например, QuestionText). Я также оставил базовый класс, потому что он оказался не чем иным, как сквозным и лишним лишним слоем. Возможно, это не совсем то, что вы ищете, но я надеюсь, что это поможет вам.

Во-первых, вот так все:
Редактировать: Обратите внимание, как теперь все они могут рассматриваться как не общие IProblem.

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: Вот, не общий интерфейс так много проблем можно использовать в списке и обрабатывают таким же образом:

public interface IProblem 
{ 
    object GetResponse(); 
} 

Вот интерфейс:
Edit: Обратите внимание, что теперь реализуется не общий интерфейс.

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

А вот классы:
Edit: Обратите внимание на новый GetResponse() методы.

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; 
    } 
} 
+0

одна проблема bob, мне действительно нужно получить доступ к ответу в не универсальном интерфейсе .. как вы думаете, это была бы большая проблема? –

+0

Ну, если ответ будет разным типам, тогда вам нужно будет рассматривать его как объект, как в вашем примере. Зачем вам нужен не общий интерфейс? –

+0

, потому что я планирую иметь Список и сохранять в XMLFile ответы. Я думал делать что-то вроде использования foreach и сохранения значений в файле. –