我这里有一个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
}
}
答案 0 :(得分:3)
这很简单:
您的班级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
)来增强此示例具体级别。
它在很大程度上取决于之后的用法......
如果您需要对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作为基本类型,派生类将能够将其用作特定类型。