C# 泛型方法正在拾取基类的类型
我对以下类进行了裁剪,以仅显示基本结构:C# 泛型方法正在拾取基类的类型,c#,generics,inheritance,C#,Generics,Inheritance,我对以下类进行了裁剪,以仅显示基本结构: public abstract class BaseModel { public bool PersistChanges() { // Context is of type "ObjectContext" DatabaseHelper.Context.SafelyPersistChanges(this); } } public static class ObjectContextExtensions {
public abstract class BaseModel {
public bool PersistChanges() {
// Context is of type "ObjectContext"
DatabaseHelper.Context.SafelyPersistChanges(this);
}
}
public static class ObjectContextExtensions {
public static bool SafelyPersistChanges<T>(this ObjectContext oc, T obj) {
// Persist the object using a transaction
}
}
[Persistent("LEADS")]
public class Lead : BaseModel {
// Extra properties
}
public class LeadsController : Controller {
public ActionResult Save(Lead lead) {
lead.PersistChanges()
}
}
我的Lead类派生自BaseModel,它包含一个使用事务将对象的更改持久化到数据库的方法。我使用扩展方法实现了事务持久化。问题是,通过将此消息传递给BaseModel类中的safelyPersistenceChanges,扩展方法上的泛型T被设置为BaseModel。但是,由于BaseModel没有被标记为持久对象(它不能是持久对象),所以ORM框架会抛出一个异常
例如:
Lead lead = LeadRepository.FindByNumber(2);
lead.SalesmanNumber = 4;
// Calls "ObjectContextExtensions.SafelyPersistChanges<BaseModel>(BaseModel obj)"
// instead of "ObjectContextExtensions.SafelyPersistChanges<Lead>(Lead obj)"
lead.PersistChanges();
上面的块引发以下异常:
无法为没有持久属性的类型“SalesWeb.Data.BaseModel”创建映射
有什么想法吗?我会以不同的方式设计它,让public bool PersistChanges调用一个虚拟方法,它在每个子类中都被重写。我会以不同的方式设计它,让public bool PersistChanges调用一个虚拟方法,扩展方法在编译时静态绑定。在调用SafelyPersistChanges时,它被类型化为BaseModel,因此是您的异常。为了获得您想要的行为,您需要执行一个带有大量强制转换的丑陋if语句,或者强制调用派生类 使持久化更改成为抽象方法。然后使用完全相同的代码在派生类中实现调用
public class Lead {
public override bool PersistChanges() {
// Context is of type "ObjectContext"
DatabaseHelper.Context.SafelyPersistChanges(this);
}
}
现在,这将正确地引导扩展方法在编译时静态绑定。在调用SafelyPersistChanges时,它被类型化为BaseModel,因此是您的异常。为了获得您想要的行为,您需要执行一个带有大量强制转换的丑陋if语句,或者强制调用派生类 使持久化更改成为抽象方法。然后使用完全相同的代码在派生类中实现调用
public class Lead {
public override bool PersistChanges() {
// Context is of type "ObjectContext"
DatabaseHelper.Context.SafelyPersistChanges(this);
}
}
现在这将是正确的引导,因此,您需要一个单一的实现,它根据调用方已知的类型而变化。听起来像是泛型药的工作
public static bool PersistChanges<T>(this T source)
where T : BaseModel
{
// Context is of type "ObjectContext"
//static property which holds a Context instance is dangerous.
DatabaseHelper.Context.SafelyPersistChanges<T>(source);
}
因此,您需要一个单一的实现,它根据调用方已知的类型而变化。听起来像是泛型药的工作
public static bool PersistChanges<T>(this T source)
where T : BaseModel
{
// Context is of type "ObjectContext"
//static property which holds a Context instance is dangerous.
DatabaseHelper.Context.SafelyPersistChanges<T>(source);
}
您可以使用以下方法解决此问题:
这是可行的,但我可能会遵循其他建议,使用虚拟方法。您可以使用以下方法解决此问题:
这会管用的,但我可能会按照其他建议使用虚拟方法。谢谢!这会造成代码重复,但我想这只是我不得不做出的牺牲。从好的方面来说,它给了模型在坚持自己之前执行其他操作的机会。谢谢!这会造成代码重复,但我想这只是我不得不做出的牺牲。从好的方面来说,它给了模型在坚持自己之前执行其他操作的机会。