2011-12-20 5 views
0

У меня есть вспомогательный класс сопоставления данных, который использует обобщения и отражение.Ссылка на производный объект в базовом классе

Поскольку я использую отражение и обобщения в моем классе-помощнике, код для стандартных операций CRUD идентичен всем моим бизнес-объектам (как видно из метода базового класса Create()), поэтому я пытаюсь используйте базовый класс BusinessObject для обработки повторяющихся методов.

Я хочу, чтобы базовый класс мог вызвать мои общие методы DataUtils, которые, например, принимают ссылку на объект бизнес-объекта, чтобы заполнить параметры SQL.

DataUtils.CreateParams ожидает объект типа T и bool (указывает на вставку или обновление).

Я хочу передать «это», представляющий мой производный объект базовым классом, но я получаю ошибку компиляции «Лучшее перегруженное совпадение содержит недопустимые параметры».

Если я реализую Create() в производном классе и передаю метод Create базового класса ссылку на «this», он работает, но я все равно реализую все методы CRUD, идентично, в каждом бизнес-объекте класс. Я хочу, чтобы базовый класс обрабатывал их.

Возможно ли, чтобы базовый класс вызывал метод и передавал ссылку на производный объект?

Вот мой базовый класс:

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

     } 
    } 
} 

}

И производный класс:

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

Ах, [CRTP] (http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx) – SLaks

ответ

2

Просто бросить this в T:

dataUtils.CreateParams((T)this, true); 

Если вы создадите public class Evil : BusinessObject<Good>, это вызовет исключение InvalidCastException.

+0

Спасибо - я пробовал то, что бросает: Невозможно преобразовать тип 'Entities.BusinessObject ' в 'T' – Ripside

+0

Это ошибка _compile-time_; это не брошено. Добавьте ', class' в общее ограничение. – SLaks

+0

Конечно. Однако это не помогло. 'public abstract class BusinessObject где T: class, new()'. Чтобы уточнить и удалить внешнюю помощь из уравнения, я буду использовать это для тестирования (та же ошибка): 'T myEntity = (T) this;' – Ripside

Смежные вопросы