2013-06-03 3 views
2

다음 예제를 가정 해보십시오. 데이터베이스 연결 처리에 대한 일반적인 접근법. DbConnection.BeginTransaction() (System.Data.Common에서) DbTransaction 인스턴스를 반환합니다. 명시 적으로 명시 했으므로 명시 적으로 캐스팅해야하는 이유는 무엇입니까?제네릭 형식으로 다시 캐스팅

internal abstract class ADatabase<DbCommandType, DbConnectionType, DbTransactionType> : IDisposable 
    where DbCommandType : DbCommand, new() 
    where DbConnectionType : DbConnection, new() 
    where DbTransactionType : DbTransaction, new() 
{ 
    DbConnectionType _connection; 
    DbTransactionType _transaction; 

    void Foo() 
    { 
     _transaction = _connection.BeginTransaction(); // <-- Error.. 
    } 
} 

내가지고있어 오류가

암시 'DbTransactionType'에 유형 'System.Data.Common.DbTransaction을'변환 할 수 없습니다 오류 1입니다. 명시 적 변환은 (당신이 캐스트를 누락?) 내가 캐스팅 할 수 물론

, 존재하지만 문제는 이유입니까?

답변

3

일반은 DbTransactionTypeDbTransaction클래스 또는에서 파생 된 클래스 여야한다는 제약 조건이 있습니다.

하이라이트를 사용하여 명시 적으로 캐스팅하지 않아야한다는 것이 분명해야합니다.

그러나 명확하지 않은 경우 : BeginTransaction의 반환 값은 DbTransaction의 인스턴스입니다. _transaction의 유형은 서브 클래스DbTransaction 일 수있는 DbTransactionType입니다. 캐스트하지 않고 하위 클래스의 변수에 기본 클래스의 변수를 지정할 수 없습니다. 그리고 기본 클래스의 변수에 실제로 해당 하위 클래스의 인스턴스가 포함되어있는 경우에만 캐스트가 작동합니다.

이 문제를 생각할 때 DbTransactionTypestringDbTransaction으로 바꾸고 object으로 대체하십시오. 이제 문제는 즉시 분명 해져야합니다.

+0

정확히 내 지점. 그런데 왜 오류가 있습니까? – Odys

+0

@odyodyodys : 제 답변을 다시 읽어보십시오. 'string'에 할당하고자 할 때 왜 객체를 던져야하는지 묻는 것과 같습니다. –

+0

'public 추상 클래스 DbConnection.BeginTransaction()'은'DbTransaction'을 반환하고'객체'는 반환하지 않습니다. 이 잘못이라면 저를 시정하십시오. – Odys

3

DbTransactionType에서 DbTransaction또는 임의의 하위 클래스을 매개 변수없는 생성자가있는 경우에만 제한하십시오. 따라서 DbTransaction 대신 임의의 하위 클래스를 사용할 수 있지만 다른 방향에서는 동일하지 않으며 DbTransactionType은 이러한 하위 클래스를 참조 할 수 있으므로 DbTransaction이라는 할당이 문제가 될 수 있습니다.

관련 문제