Программирование для супертипа в C # - PullRequest
1 голос
/ 16 марта 2012

У меня проблема с OO.У меня есть две сессии, которые имеют общие свойства и конкретные свойства.Я создал базовый класс и инкапсулировал все общие свойства / методы.Два сеанса имеют общий тип, называемый Ranges, который также имеет общее свойство и конкретное свойство для сеансов.Поэтому я подумал, что мог бы в этом случае запрограммировать супертип и построить экземпляр во время выполнения.

public class Level
{
    private readonly Ranges _range;

    public Level(Ranges range)
    {
        _range = range;
    }

    public Ranges Range
    {
        get { return _range; }
    }

    public void CommonMethod()
    {
        throw new NotImplementedException();
    }

    public int CommonProperty;
}

public class ALevel : Level
{
    public ALevel()
        : base(new ARange())
    {

    }

    public int ALevelProperty;
}

public class BLevel : Level
{
    public BLevel()
        : base(new BRange())
    {

    }

    public int BLevelProperty;
}

public class Ranges
{
    public int CommonRangeProperty;
}

public class ARange : Ranges
{
    public int ARangeProperty;

    public ARange() 
    {

    }
}

public class BRange : Ranges
{
    public int BRangeProperty;
}

public class ASession
{
    public ASession()
    {
        Level = new ALevel();
    }

    public ALevel Level { get; set; }
}

public class BSession
{
    public BSession()
    {
        Level = new BLevel();
    }

    public BLevel Level { get; set; }
}

Когда я создаю объект сеанса, он не содержит конкретного свойства Ranges ASession.Я могу получить доступ только к свойству базового класса aSession.Level.Range.CommonRangeProperty = 1;но я не могу получить доступ к определенному свойству aSession aSession.Level.Range.ARangeProperty.

Я что-то здесь не так делаю?

Ответы [ 2 ]

3 голосов
/ 16 марта 2012

все довольно просто:

ваш класс Level устанавливает тип Range на Ranges (не конкретный ARange или BRange). Вы должны работать с дженериками, например:

public abstract class Level<TRange>
   where TRange : Ranges
{
    private readonly TRange _range;
    protected Level(TRange range)
    {
        this._range = range;
    }
    public TRange Range
    {
        get
        {
            return this._range;
        }
    }
}

public class ALevel : Level<ARange>
{
    public ALevel()
        : base (new ARange())
    {
    }
}

Вы можете взять этот пример еще дальше:

public abstract class Level<TRange>
   where TRange : Ranges/*, new()*/ // i'm not sure about the new() ... have no compiler access right now to check!
{
    private readonly TRange _range = new TRange();
    public TRange Range
    {
        get
        {
            return this._range;
        }
    }
}

public class ALevel : Level<ARange>
{
}

наш, вы можете представить другого участника в ALevel, например:

public class ALevel : Level
{
   public ARange ARange;
}

Вы можете улучшить этот пример, сделав Range в Level виртуальным и переопределив Range (с перенаправлением на бетон ARange или BRange) в конкретных уровнях.

это сильно зависит от использования потом ... если вам нужен общий доступ к свойству Range как Ranges, вы должны ввести другой базовый класс (без универсального ограничения), чтобы ввести базовый член, который вы можете переопределить в своем базовом базовом классе. так что вы можете разыграть экземпляр ALevel до Level (без базового класса, который вы должны были бы разыграть до Level<TRange>, который обладает знанием конкретного TRange) ...

1 голос
/ 16 марта 2012

Если я правильно понимаю вашу проблему, вам нужно использовать дженерики, чтобы делать то, что вы пытаетесь выполнить. Ваш код будет выглядеть примерно так:

public class Level<TRange>
    where TRange: Ranges
{
    private readonly TRange _range;

    public TRange Range
    {
        get
        {
            return this._range;
        }
    }
}

public class ALevel : Level<ARange>
{

}

Суперкласс затем сможет использовать Range в качестве базового типа, а ваши производные классы смогут использовать его в качестве своего определенного типа.

...