在c#中编写超类型

时间:2012-03-16 06:29:27

标签: c# oop supertype

我这里有一个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; }
}

当我创建会话对象时,它不包含ASession的特定Ranges属性。 我只能访问基类的属性     aSession.Level.Range.CommonRangeProperty = 1; 但我无法访问aSession的特定属性     aSession.Level.Range.ARangeProperty。

我在这里做错了吗?

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

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

    }
}

2 个答案:

答案 0 :(得分:3)

这很简单:

您的班级LevelRange的类型设置为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(重定向到具体的BRangeRange)来增强此示例具体级别。

它在很大程度上取决于之后的用法...... 如果您需要对proprety Ranges作为ALevel进行泛型访问,则应引入另一个基类(没有通用约束)来引入基类成员,您可以在通用基类中覆盖它。所以你可以将Level的实例强制转换为Level<TRange>(没有基类,你必须强制转换为具体TRange知识的{{1}})。

答案 1 :(得分:1)

如果我正确理解您的问题,您需要使用泛型来完成您想要完成的任务。您的代码看起来像

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

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

public class ALevel : Level<ARange>
{

}

超类将能够使用Range作为基本类型,派生类将能够将其用作特定类型。