我想实现抽象工厂模式以最大化代码效率来读取我的同步参考类型。为实现这一点,我有以下实现
并实现模式我实现了以下内容:
RefEntityFactor 类的代码是:
public class RefEntityFactory<T> : IRefEntityFactory<T> where T : IRefEntity
{
public List<T> Search(string sp_name, int? id, string code, int? statusid)
{
List<T> irefs = new List<T>();
string procName = sp_name;
SqlConnection conn = null;
using (conn = GetConnection())
{
SqlCommand cmd = new SqlCommand(procName, conn);
cmd.CommandType = CommandType.StoredProcedure;
if (id.HasValue)
cmd.Parameters.AddWithValue("@ID", id.Value);
if (!string.IsNullOrEmpty(code) && !string.IsNullOrWhiteSpace(code))
cmd.Parameters.AddWithValue("@CODE", code.Trim());
if (statusid.HasValue)
cmd.Parameters.AddWithValue("@STATUS", statusid.Value);
SqlDataReader rd = cmd.ExecuteReader();
while (rd.Read())
{
RefEntity refe = new RefEntity();
refe.Id = int.Parse(rd["ID"].ToString());
refe.Code = rd["CODE"].ToString();
refe.Status = short.Parse(rd["STATUS"].ToString());
IRefEntity iref = (IRefEntity)refe;
irefs.Add((T)iref); // Exception will be THROWN HERE!!!!
}
rd.Close();
}
return irefs;
}
}
然后我为spesific类型实现了一个类:
作为
public static List<IPaymentType> SearchPaymentTypes(int? id, string code, int? statusid)
{
RefEntityFactory<IPaymentType> fact = new RefEntityFactory<IPaymentType>();
return fact.Search(@"[dbo].[SEARCH_PAYMENTTYPES]", id, code, statusid);
}
但很明显,当我运行代码时,它会在我标记为注释的行处抛出异常。
如何更正我的实施?
问候。
答案 0 :(得分:1)
最终,这是因为RefEntity
不属于T
类型,您是否尝试通过构建新的T
来采用该方法,因此在您的while循环中会出现这样的情况:
T refe = new T();
refe.Id = int.Parse(rd["ID"].ToString());
refe.Code = rd["CODE"].ToString();
refe.Status = short.Parse(rd["STATUS"].ToString());
irefs.Add(ref);
您还需要扩展generic constraint以限制T
以要求无参数构造函数,例如:
public class RefEntityFactory<T> : IRefEntityFactory<T> where T : IRefEntity, new()
您也应该按照以下方式更改 SearchPaymentTypes 以使其正常工作:
public static List<IPaymentType> SearchPaymentTypes(int? id, string code, int? statusid)
{
RefEntityFactory<PaymentType> fact = new RefEntityFactory<PaymentType>();
List<PaymentType> list = fact.Search(@"[dbo].[SEARCH_PAYMENTTYPES]", id, code, description, statusid);
return list.Select(x => (IPaymentType)x).ToList();
}
答案 1 :(得分:0)
问题是RefEntityFactory创建了RefEntity对象。 RefEntity不能转换为IPaymentType,因为它们不会实现IPaymentType。
您不需要使用通用参数来实现抽象工厂模式。抽象工厂的方法可以返回IRefEntity:
interface IRefEntityFactory
{
List<IRefEntity> Search(string sp_name, int? id, string code, int? statusid);
}
具体工厂将返回实现IRefEntity的各种具体实体类型:
class PayrollEntityFactory : IRefEntityFactory
{
public List<IRefEntity> Search(string sp_name, int? id, string code, int? statusid)
{
List<IRefEntity> ret = new List<IRefEntity>();
ret.Add(new PaymentType());
return ret;
}
}
或
class NnnnEntityFactory : IRefEntityFactory
{
public List<IRefEntity> Search(string sp_name, int? id, string code, int? statusid)
{
List<IRefEntity> ret = new List<IRefEntity>();
ret.Add(new NnnnType());
return ret;
}
}
或者抽象工厂可以是抽象类而不是接口。这将允许所有实现共享公共代码,并避免重复大部分例如SQL查询。但是实际的具体对象(例如工资单)创建无法共享,每个对象的构造都需要是唯一的。