1

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

    }
}
4

2 回答 2

3

这很简单:

您的班级Level将类型设置RangeRanges(不是特定的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)......

于 2012-03-16T06:34:59.443 回答
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 作为基类型,而您的派生类将能够将其用作它们的特定类型。

于 2012-03-16T06:42:03.807 回答