Параметр метода переопределения наследования С# с классом потомков

63
4

Я попытался обобщить этот вопрос так, чтобы он по-прежнему имел смысл и, тем не менее, не имел всего кода моих реальных классов. В принципе, то, что я хотел бы сделать, это иметь метод в производном классе, переопределить один из его методов предков, но использовать параметр, который является производным от класса, который является параметром в сигнатуре метода предка. Надеюсь, этот код объясняет это лучше:

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;
}
}

Я не хочу повторять код в методе SaveChanges для всех потомков BaseVehicle; однако все потомки BaseVehicle будут использовать потомки differnet BaseShape. Кодекс выше, конечно, не будет строиться, и пока я понимаю, почему (или, по крайней мере, думаю, что я это делаю), я все время царапаю голову, пытаясь понять, как правильно его разработать.

спросил(а) 2021-01-25T18:37:17+03:00 5 месяцев назад
1
Решение
63

Вы можете выполнить то, что вам нужно, обновив классы своего автомобиля так:

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;
}
}

Это решение, реализующее дженерики, как упоминал Джон Скит.

ответил(а) 2021-01-25T18:37:17+03:00 5 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема