我试图概括这个问题,以便它仍然有意义但却没有我实际课程的所有代码。基本上,我想要做的是在派生类中使用方法覆盖其祖先方法之一,但使用从作为祖先方法签名中的参数的类派生的参数。希望这段代码能更好地解释它:
public abstract class BaseShape
{
public int Id { get; set; }
public bool Active { get; set; }
public abstract bool Modified();
public abstract void Validate(List<string> errors);
}
public class DescendantShape : BaseShape
{
public int AnotherProperty { get; set; }
public override bool Modified()
{
return true;
}
public override void Validate(List<string> errors)
{
//
}
}
public abstract class BaseVehicle
{
public void SaveChanges(BaseShape shape)
{
if (!shape.Modified()) return;
var errorList = new List<string>();
shape.Validate(errorList);
if (errorList.Count > 0)
{
var sb = new StringBuilder();
foreach (string s in errorList)
{
sb.Append(s + Environment.NewLine);
}
throw new Exception(sb.ToString());
}
WriteToStorage(shape);
if (!shape.Active)
MarkInactive(ref shape);
}
public abstract void WriteToStorage(BaseShape shape);
public abstract void MarkInactive(ref BaseShape shape);
}
public class DescendantVehicle : BaseVehicle
{
public override void WriteToStorage(DescendantShape shape)
{
//
}
public override void MarkInactive(ref DescendantShape shape)
{
shape = null;
}
}
我不想为所有BaseVehicle的后代重复SaveChanges方法中的代码;但是,所有BaseVehicle的后代都将使用BaseShape的不同后代。上面的代码当然不会构建,虽然我理解为什么(或者至少认为我这样做),但我整个上午一直在试图弄清楚如何正确设计它。
答案 0 :(得分:1)
您可以通过更新车辆类来完成您的目标:
public abstract class BaseVehicle<T> where T : BaseShape
{
public void SaveChanges(T shape)
{
if (!shape.Modified()) return;
var errorList = new List<string>();
shape.Validate(errorList);
if (errorList.Count > 0)
{
var sb = new StringBuilder();
foreach (string s in errorList)
{
sb.Append(s + Environment.NewLine);
}
throw new Exception(sb.ToString());
}
WriteToStorage(shape);
if (!shape.Active)
MarkInactive(ref shape);
}
public abstract void WriteToStorage(T shape);
public abstract void MarkInactive(ref T shape);
}
public class DescendantVehicle : BaseVehicle<DescendantShape>
{
public override void WriteToStorage(DescendantShape shape)
{
//
}
public override void MarkInactive(ref DescendantShape shape)
{
shape = null;
}
}
这是Jon Skeet提到的实施generics的解决方案。