J'ai une classe auxiliaire de mappage de données qui utilise des génériques et des réflexions. Comme j'utilise la réflexion et les génériques dans ma classe d'aide, le code des opérations CRUD standard est identique dans tous mes objets métier (comme dans la méthode de classe Create(), donc j'essaie de utilisez une classe BusinessObject de base pour gérer les méthodes répétitives.Référencement d'un objet dérivé dans une classe de base
Je souhaite que la classe de base puisse appeler mes méthodes génériques DataUtils, qui acceptent par exemple une référence à l'objet d'objet métier dérivé pour remplir les paramètres SQL.
DataUtils.CreateParams attend un objet de type T et un booléen (indique insertion ou mise à jour). Je veux passer "ceci", représentant mon objet dérivé la classe de base, mais je reçois erreur de compilation "La meilleure correspondance surchargée contient des paramètres invalides." Si j'implémente Create() dans la classe dérivée et que je passe la méthode Create de la classe de base en référence à "this", cela fonctionne, mais j'implémente toujours toutes les méthodes CRUD, à l'identique, dans chaque objet métier classe. Je veux que la classe de base les gère.
Est-il possible qu'une classe de base appelle une méthode et transmette une référence à l'objet dérivé?
Voilà ma classe de base:
public abstract class BusinessObject<T> where T:new()
{
public BusinessObject()
{ }
public Int64 Create()
{
DataUtils<T> dataUtils = new DataUtils<T>();
string insertSql = dataUtils.GenerateInsertStatement();
using (SqlConnection conn = dataUtils.SqlConnection)
using (SqlCommand command = new SqlCommand(insertSql, conn))
{
conn.Open();
//this line is the problem
command.Parameters.AddRange(dataUtils.CreateParams(obj, true));
return (Int64)command.ExecuteScalar();
}
}
}
}
Et une classe dérivée:
public class Activity: BusinessObject<Activity>
{
[DataFieldAttribute(IsIndentity=true, SqlDataType = SqlDbType.BigInt)]
public Int64 ActivityId{ get; set; }
///...other mapped fields removed for brevity
public Activity()
{
ActivityId=0;
}
//I don't want to have to do this...
public Int64 Create()
{
return base.Create(this);
}
Ah, [le CRTP] (http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx) – SLaks