2016-06-20 4 views
4

다른 클래스가 확장하는 DbContext 클래스가 있습니다. 예를 들어 :C# 제네릭 용으로이 클래스를 사용하십시오.

class Contact extends DbContext {} 

클래스 DbContext 내부, 내가 제네릭에 DbContext를 확장 중 클래스 사용하려면 :

public static IEnumerable<DBContext> GetAll() 
    { 
     var sql = "SELECT * FROM " + TableName(); 
     return DB().Fetch<DBContext> (sql); 
    } 

주를 IEnumerable < DBContext> 여기.

위의 코드는 괜찮지 만 매번 형 입력해야합니다.

public static IEnumerable<thisClass> GetAll() 
{ 
    var sql = "SELECT * FROM " + TableName(); 
    return DB().Fetch<thisClass> (sql); 
} 

주를 IEnumerable < thisClass> 여기에 : 나는 같은 thisClass를 얻을 수 있습니다.

DStanley의 코멘트 후 :

내가하려고 노력 :

public static IEnumerable<T> GetAll<T>() 
    { 
     var sql = "SELECT * FROM " + TableName(); 

     return DB().Fetch<T> (sql); 
    } 

하지만이 같은 전화를하고 싶지 않은 : 깨끗하지

Contact.GetAll<Contact>(); 

합니다. 권리?

참고 : TableName()은 걱정할 필요가 없습니다. 그것은 그것이 호출되는 클래스를 기반으로하는 방식으로 SQL 메소드를 가져옵니다.

+3

'public static IEnumerable GetAll () 여기서 T : DbContext'로 선언하고 토끼 구멍까지 얼마나 멀리 내려갈 수 있는지보십시오. 'TableName()'이 무엇을하는지 그리고/또는 그것이 generic 일 필요가 있는지는 명확하지 않다. –

+4

또는 https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern – SLaks

+0

@D 스탄 틀리를 사용하십시오. 실제로 했었지만 매번 수업을 통과하기를 원하지 않습니다. 내 질문에 업데이 트됩니다 – tika

답변

4

재귀적인 제네릭 제약 조건을 적용하여 작업 할 수 있습니다.

먼저 DbContext<T> 일반 (DbContext을 일반으로 변경하거나 상속 레이어 추가)이 필요합니다.

public class DbContext<T> : DbContext 
{ 
    public static IEnumerable<T> GetAll() 
    { 
     var sql = "SELECT * FROM " + TableName(); 

     return DB().Fetch<T> (sql); 
    } 
} 

그런 다음 일반 클래스에서 자녀 DbContext 상속합니다 :
public class Contact : DbContext<Contact> 
{ 

} 

이제 Contact.GetAll();을 쓸 수 있습니다 내부, 당신의 방법을 정의합니다.

+0

@Kookoz, 이제 그게 좋았어, 끝내. – tika

+0

F- 바운드 다형성. –

0

당신은 제네릭 형식 T 같은 클래스 매개 변수의 이름을 지정하고 다음은과 같이 구현해야 어떤 인터페이스 이름을 지정할 수 있습니다 : 당신이 한이 구현 귀하의 방법으로 모든 클래스를 전달할 수 있습니다이와

public static IEnumerable<T> GetAll() where T : DBContext 
    { 
    var sql = "SELECT * FROM " + TableName(); 
    return DB().Fetch<DBContext> (sql); 
    } 

DBContext 인터페이스

MSDN에서 here을 더 읽을 수 있습니다.

편집 : 의견에 D Stanley가 말한 것을 보지 못했습니다. 이것이 그의 답변이기도합니다.

+0

그 친구를 사용해 보았습니다. 고마워,하지만 어떻게 다른 클래스에서 그 메소드를 호출 할 것을 제안하겠습니까? Person.GetAll () 나는 그다지 깨끗하지 못합니다. 사람을 두 번 쓴다. – tika

1

이 호출의 결과를 IEnumerable<Contact> 유형의 변수에 할당하면 올바른 방법을 호출해야합니다.

.

+0

예. 그러나 그것은 타입 캐스팅입니다. 나는 내 질문에 언급했다. 고마워 친구하지만, 내가 몹시 기대하는 것은 아니다. 또한 나는 여기에 방법들을 연결할 수 없다. – tika

+0

나는 어떤 방법도 연결하지 않는다. –

+0

아니, 그건 타입 캐스팅이 아니에요. 이것은 런타임에하는 일입니다. 이것은 타겟 변수의 힌트를 기반으로 메소드를 찾는 컴파일러 일뿐입니다. –

관련 문제