我有一个包含两个实体的表格, StaticProgram 和 DynamicProgram 。该表中有一列名为ProgramType,用于确定程序是“静态”还是“动态”类型。虽然这两个实体存储在一个表中(我猜是因为静态和动态程序的原始字段完全相同),但从业务角度来看,这是两个非常不同的实体。
因此,我创建了两个类 StaticProgram 和 DynamicProgram 。但是,我不想创建两个单独的数据访问类,因为它将完全相同的代码复制两次。我尝试创建一个“Program”类作为基类并继承StaticProgram和DynamicProgram类,但不支持向下转换,因此我无法从数据访问类返回“Program”对象并将其转换为“StaticProgram”类等。 / p>
那么,我的选择是什么?我可以创建 IProgram 界面,并使 StaticProgram 和 DynamicProgram 实现该界面并让我的数据访问类返回 IProgram ?或者如何使数据访问方法成为通用方法(如果这是可能的并且是推荐的方法,我需要一些帮助,因为我对泛型没有太多的了解)?还有其他建议吗?
感谢您的帮助!!
更新 数据访问方法确实是静态的:
public static class ProgramDataMapper
{
public static Program GetProgram(int programID)
{
Program p = new Program();
// database stuff
p.Name = reader["Name"].ToString();
...
return p;
}
}
基类如下:
public class Program
{
// Properties
public static Program GetProgram(int programID)
{
return ProgramDataMapper.GetProgram(programID);
}
}
最后是派生类:
public class DynamicProgram : Program
{
// Additional Business Related Properties
public new static DynamicProgram GetProgram(int programID)
{
return (DynamicProgram)Program.GetProgram(programID);
}
}
这个编译得很好,但我得到了一个不能在运行时将“Program”强制转换为“DynamicProgram”异常。
另外,通用方法怎么样?除非我不在这里,但是,理论上,我们不能做类似的事情:
public static IProgram GetProgram<T>(int programID) where T : IProgram
{
IProgram program;
Type returnType = typeof(T);
if(returnType is StaticProgram)
{
program = new StaticProgram();
}
else if(returnType = DynamicProgram)
{
program = new DynamicProgram();
}
//if (T is StaticProgram)
//{
// returnValue = new StaticProgram();
//}
//else if (T is DynamicProgram)
//{
// returnValue = new DynamicProgram();
//}
// db operations
}
当然上面的代码不起作用。我得到“给定的表达式永远不会是提供的类型(StaticProgram)类型。”
答案 0 :(得分:1)
这个怎么样:
public static class ProgramDataMapper
{
// Change to a generic here to manufacture any class deriving from Program.
public static T GetProgram<T>(int programID)
where T : Program, new()
{
T p = new T();
// database stuff
p.Name = reader["Name"].ToString();
...
return p;
}
}
public abstract class Program
{
// Properties
// Manufacture a concrete class that derives from Program
public new static T GetProgram<T>(int programID)
where T : Program, new()
{
return ProgramDataMapper.GetProgram<T>(programID);
}
}
public class DynamicProgram : Program
{
// Additional Business Related Properties
public new static DynamicProgram GetProgram(int programID)
{
// Specifically manufacture a DynamicProgram
return Program.GetProgram<DynamicProgram>(programID);
}
}
哲学上,也许一个界面可能更适合,但是为了以最小的努力获得你必须工作的东西,这应该可以解决问题。
您发布的代码不会转换为DynamicProgram,因为您在ProgramDataMapper中专门构建了一个Program对象。虽然DynamicProgram“是一个”程序,但事实并非如此。在我在这里提供的代码中,使用泛型,构造DynamicProgram而不仅仅是程序。使用泛型也完全不需要在DynamicProgram.GetProgram方法中进行强制转换。
答案 1 :(得分:0)
我尝试创建一个“Program”类作为基类并继承StaticProgram和DynamicProgram类但不支持向下转换,因此我无法从数据访问类返回“Program”对象并将其强制转换为“StaticProgram”类等
很奇怪,因为这应该有效:
public Program GetProgram(){
if(someDataCoulumn.Equals("Static")) {
return new StaticProgram(...);
} else {
return new DynamicProgram(...);
}
}
public void Caller(){
var p = GetProgram();
var sp = p as StaticProgram;
if(sp != null) {
DoSomethingWithStaticProgram(sp);
} else {
var dp = p as DynamicProgram;
if(dp != null){
DoSomethingWithDynamicProgram(dp);
} else {
throw new SomeBusinessException("Program is neither Static not Dynamic, instead it's " + p.GetType().FullName);
}
}
}
答案 2 :(得分:0)
要检查的是你的哪种方法不违反LSP(Liskov替代原则)。既然你自己说过它们是两个非常不同的东西,继承模型的使用在这里就无法真正起作用。冗余代码可以被剥离到第三个类,它会通过静态方法暴露自己,或者你可以在你的两个程序对象中引用这个'helper'类。
答案 3 :(得分:0)
如何使用静态类来完成所有DataAccess?