2011-12-20 2 views
0

나는 generics 및 리플렉션을 사용하는 데이터 매핑 도우미 클래스가 있습니다.기본 클래스에서 파생 된 개체 참조

헬퍼 클래스에서 리플렉션 및 제네릭을 사용하고 있으므로 표준 CRUD 작업 코드는 모든 비즈니스 개체에서 동일합니다 (기본 클래스 Create() 메서드에서 볼 수 있음). 기본 BusinessObject 클래스를 사용하여 반복적 인 메서드를 처리합니다.

예를 들어 SQL 매개 변수를 채우기 위해 파생 된 비즈니스 객체 객체에 대한 참조를 받아들이는 일반 DataUtils 메소드를 기본 클래스에서 호출 할 수있게하려고합니다.

DataUtils.CreateParams는 T 유형의 객체와 bool (삽입 또는 업데이트를 나타냄)을 필요로합니다.

내 파생 된 개체를 기본 클래스로 나타내는 "this"를 전달하려고합니다. 그러나 "최적의 오버로드 된 일치에 잘못된 매개 변수가 있습니다"라는 오류가 발생합니다.

파생 클래스에서 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(); 

     } 
    } 
} 

}

그리고 파생 클래스 : 그냥 Tthis 캐스팅

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

:

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