Frage

I have an OO problem here. I have two sessions which has common properties and specific properties. I created a base class and encapsulated all the common properties/methods. Two session has a common type called Ranges, which again has common property and specific property for the sessions. Hence I thought I could program to supertype in this case and build the instance at runtime.

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

When I create a session object, it doesn't contain specific Ranges property of ASession. I can access only the base class's property aSession.Level.Range.CommonRangeProperty = 1; but am not able to access the aSession's specific property aSession.Level.Range.ARangeProperty.

Am I doing something wrong in here?

public class Test
{
    public static void Main(string[] args)
    {
        ASession aSession = new ASession();

        aSession.Level.Range.CommonRangeProperty = 1;
        //Not able to see ARangeProperty

    }
}
War es hilfreich?

Lösung

it's pretty simple:

your class Level sets the type of Range to Ranges (not the specific ARange nor BRange). you should work with generics, eg:

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

you can take this example even further:

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

our you could introduce another member in ALevel, like so:

public class ALevel : Level
{
   public ARange ARange;
}

you could enhance this example by making Range in Level virtual and overriding Range (with a redirect to the concrete ARange or BRange) in the concrete Levels.

it heavily depends on the usage afterwards... if you need generic access to the proprety Range as Ranges you should introduce another base class (without generic constraint) to introduce a base member, which you can override in your generic base class. so you can cast an instance of ALevel to Level (w/o the base class you would have to cast to Level<TRange> which the knowledge of the concrete TRange) ...

Andere Tipps

If I understand your problem correctly you need to use generics to do what you are trying to accomplish. Your code will look something like

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

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

public class ALevel : Level<ARange>
{

}

The super class will then be able to use Range as the base type and your derived classes will be able to use it as their specific type.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top