结构......
abstract class Unit
{
int Id;
}
class Measure : Unit
{
int Current;
int Baseline;
}
class Weight : Unit
{
int Minimum;
int Maximum;
int Current;
}
我基本上想添加一个“添加”方法,用于将两个度量添加到一起,或者将两个权重一起添加。但它需要在Unit基类中。所以基本上如果我有
List<Units> units = new List<Unit>();
List<Units> otherUnits = new List<Unit>();
// populate units with various Measures and Weights.
// populate otherUnits with various Measures and Weights.
foreach(Unit u in units)
{
u.Add(
// add something from the otherUnits collection. Typesafe, etc.
);
}
我试过..
public abstract T Add<T>(T unit) where T : Unit;
单元类中的,但是当我尝试用适当的类填充“T”时,我得到了关于它如何不是继承类中的适当标识符的错误。有什么想法吗?
答案 0 :(得分:4)
您需要更改Unit
抽象类以采用泛型类型:
abstract class Unit<T>
然后你可以添加Add
抽象方法:
void Add(T unit);
所以你的测量和重量等级现在看起来像:
class Measure : Unit<Measure>
class Weight : Unit<Weight>
或者,将以下抽象方法添加到Unit
:
abstract void Add(Unit unit);
然后你需要在继承类中使用类型检查来约束它:
void Add(Unit unit)
{
if (unit.GetType() != this.GetType())
{
throw new ArgumentException("You can only add measurements.");
}
}
答案 1 :(得分:0)
如果你的层次结构足够稳定,你可以使用访问者模式的想法来提出这样的结论:
abstract class Unit {
public abstract Unit Add(Unit unit);
public virtual Measure Add(Measure unit) { return unit; }
public virtual Weight Add(Weight unit) { return unit; }
}
class Measure : Unit {
public override Measure Add(Measure unit) {
// ...
}
public override Unit Add(Unit unit) {
return unit.Add(this);
}
}
class Weight : Unit {
public override Weight Add(Weight unit) {
// ...
}
public override Unit Add(Unit unit) {
return unit.Add(this);
}
}
如果您预计稍后会将其他行为添加到层次结构中,您甚至可以使用真正的访问者并将其与Unit
类分开。
注意:如果Add
将更改当前实例,则if应返回void
。
答案 2 :(得分:0)
我实际上是从GenericTypeTea那里得到了这个想法,但我尝试使用不同的方法。
public interface IUnit
{
T Add<T>(T unit) where T : IUnit<T>;
}
public interface IUnit<T>
{
T Add(T unit);
}
abstract class Unit : IUnit
{
}
class Measure : Unit, IUnit<Measure>
{
public Measure Add(Measure unit)
{
throw new NotImplementedException();
}
}
class Weight : Unit, IUnit<Weight>
{
public Weight Add(Weight unit)
{
throw new NotImplementedException();
}
}
答案 3 :(得分:0)
如果您必须使用两个基类列表:
public abstract class Unit()
{
public abstract Unit Add(Unit other);
public void MatchType(Unit other)
{
if(this.GetType() != other.GetType())
throw new ArgumentException("Units not of same type");
}
}
...然后在每个派生类中实现以下内容:
public override void Add(Unit other)
{
MatchType(other);
//actual implementation
}
然后使用实际的Add实现在派生类中扩展此功能。
老实说,我没有看到你想要做的事情的重点。除非两个列表仅包含Measures或Only Weights,否则它将无效,并且您只是通过将类型检查放入Unit中而将该事实隐藏起来。那只是在寻找麻烦。
我将按如下方式定义您拥有这两个列表的代码:
public List<T> AddLists<T>(List<T> firstList, List<T> secondList) where T:Unit
{
//your code to add elements
}
...然后使用通用的Unit.Add()方法,如下所示:
public static void Add<T>(this T item, T other) where T:Unit
{
//perform something that works like item += other
}
您必须使用强力键入权重或计量的列表。您可以尝试使用Linq转换List的泛型参数:
listOfMeasures = listOfUnits.OfType<Weight>().ToList();
当然,这会导致权重从列表中过滤掉,但这对您有利:
listOfWeights = listOfUnits.OfType<Weight>().ToList();
listOfMeasures = listOfUnits.OfType<Measure>().ToList();
var addedListOfMeasures = AddLists(listOfMeasures, otherListOfMeasures);
var addedListOfWeights = AddLists(listofWeights, otherListOfWeights);
上面的代码与我列出的通用AddLists和Unit.Add()方法一起使用,将是类型安全的,因此不会抛出任何运行时异常。做不好;您创建的任何新单元都需要添加更多代码来处理每种新类型。