У меня есть архитектура, которая опирается в основном на дженерики. В какой-то момент мне нужно отбросить базовый тип, и, как вопрос любопытства, мне интересно, смогу ли я его обойти.Попытка избежать приведения с моими генериками
Фон у нас есть несколько групп производственных линий, которые мы хотим напечатать на веб-странице. Поскольку производственные линии каждой группы есть часть той же самой информации, но и некоторые различную информацию, я использовали абстрактный класс:
public abstract class ProductionLine
{
public int LineNumber { get; set; }
public string Name { get; set; }
public double Target { get; set; }
public double Actual { get; set; }
public double Variance { get; set; }
}
А вот пример конкретной реализации:
public class TissueProductionLine : ProductionLine
{
public double Budget { get; set; }
public double PercentOnTarget { get; set; }
}
Поскольку мы «говорит о группах производственных линий, я создал абстрактный объект для размещения имени группы и все его производственных линий:
public abstract class ProductionLineGroup<T> where T : ProductionLine
{
public string Name { get; set; }
public List<T> ProductionLines { get; set; }
}
и вот конкретная реализация группы:
public class TissueProductionLineGroup : ProductionLineGroup<TissueProductionLine>
{
public string TissueType { get; set; }
}
Все это хорошо, но я хочу, чтобы иметь возможность визуализации производственной линии группы к HTML в виде ряда таблиц. Чтобы разделить мои проблемы, я создал formatters, которые будут потреблять группы и выделять необходимую разметку. Используя фабрику, я выберу соответствующий форматировщик:
public static class ProductionLineGroupFormatterFactory<T> where T : ProductionLine
{
public static ProductionLineGroupFormatter<T> GetProductionLineGroupFormatter(ProductionLineGroup<T> group)
{
if (typeof(T) == typeof(TissueProductionLineGroup))
{
return new TissueProductionLineGroupFormatter<T>();
}
throw new ApplicationException("Could not find an appropriate formatter for this Production Line type:" + typeof(T).ToString());
}
}
Фабричный метод возвращает объект с базовым типом ProductionLineGroupFormatter:
public abstract class ProductionLineGroupFormatter<T> where T : ProductionLine
{
public abstract string Render(ProductionLineGroup<T> group);
}
производный тип, который фактически выводящий является TissueProductionLineGroupFormatter:
public class TissueProductionLineGroupFormatter<T> : ProductionLineGroupFormatter<T> where T : ProductionLine
{
public override string Render(ProductionLineGroup<T> group)
{
foreach (ProductionLine line in group.ProductionLines)
{
TissueProductionLine tLine = (TissueProductionLine)line;
sb.Append(@"<tr>
<td>" + tLine.Name + @"</td>
<td>" + tLine.Actual + @"</td>
<td>" + tLine.Target + @"</td>
<td>" + tLine.Variance + @"</td>
<td>" + tLine.PercentOnTarget + @"</td>
</tr>");
}
}
return sb.ToString();
}
}
Обратите внимание на листинг, который мне нужно сделать в моей петле foreach. Я не могу понять, можно ли это избежать. Первоначально я пытался ограничить T до TissueProductionLine, так как он получен из ProductionLine, но я получаю сообщение об ошибке «Нет никакого неявного преобразования ссылок с« T »на« TissueProductionLine ». Затем я попытался создать неявный оператор, чтобы преобразования могли быть между поточная линия и TissueProductionLine, но вы не можете сделать это с помощью базовых и производных типов.
Если кто-то может пролить свет на это, я оценил бы имея мое любопытство удовлетворено! Спасибо!
Chris
Почему не может '' TissueProductionLineGroupFormatter продлить 'ProductionLineGroupFormatter ', и если это форматтер для этого конкретного типа, то каково общее ограничение типа 'T' для? –
mellamokb
Если удалить ограничение, то я получаю ошибку в моей фабрике: Не может неявно преобразовать тип «TissueProductionLineGroupFormatter» до «ProductionLineGroupFormatter» –