Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 泛型方法正在拾取基类的类型_C#_Generics_Inheritance - Fatal编程技术网

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);
}

您可以使用以下方法解决此问题:


这是可行的,但我可能会遵循其他建议,使用虚拟方法。

您可以使用以下方法解决此问题:


这会管用的,但我可能会按照其他建议使用虚拟方法。

谢谢!这会造成代码重复,但我想这只是我不得不做出的牺牲。从好的方面来说,它给了模型在坚持自己之前执行其他操作的机会。谢谢!这会造成代码重复,但我想这只是我不得不做出的牺牲。从好的方面来说,它给了模型在坚持自己之前执行其他操作的机会。