我有一个严重依赖泛型的架构设置。在某一时刻,我确实必须转换为基本类型,出于好奇,我想知道我是否可以回避它。
背景是我们有许多想要打印到网页的生产线组。由于每个组的生产线有一些相同的信息,但也有一些不同的信息,我使用了一个抽象类:
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 作为一系列表格。为了分离我的关注点,我创建了将使用组并发出所需标记的格式化程序。使用工厂,我将选择适当的格式化程序:
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' 的隐式引用转换。然后我尝试创建一个隐式运算符,以便可以进行转换在 ProductionLine 和 TissueProductionLine 之间创建,但您不能对基本类型和派生类型执行此操作。
如果有人能对此有所了解,我将不胜感激满足我的好奇心!谢谢!
克里斯