2017-04-12 9 views
3

일반 목록에서 레코드를 가져 오는 데 문제가 있습니다. 나는 모든 유형의 클래스에서 레코드를 가져오고 싶은 공통 함수를 만들었다. 다음은 샘플 코드입니다. -일반 목록에서 항목 찾기

public void Test<T>(List<T> rEntity) where T : class 
{ 
    object id = 1; 
    var result = rEntity.Where(x => x.id == id); 
} 

좋습니다. 미리 감사드립니다.

+4

당신이 무엇을 기대하는'()'테스트를 할까? 또는'Test ()'? 여러분의'T'가 제약 조건에서 훨씬 더 많이 필요로하는 것처럼 보입니다 ... –

+2

T가 클래스라는 것은 T가 id라는 속성을 가진 객체의 집합임을 의미하지 않기 때문에이 코드를 컴파일해서는 안됩니다. . –

+0

Jon, 'T'는 위의 메서드를 호출하는 동안 전달할 일반 클래스 이름입니다. 감사합니다 –

답변

4

그런 컴파일러에 대한 일반적인 질문은 '무엇이 T입니까? Jon이 언급 한 것처럼 단지 클래스 일 경우 StringBuilder 일 수도 있고 'Id'속성이 있다는 보장이 없습니다. 그래서 그것은 현재의 방식으로 컴파일되지 않습니다.

A) 방법을 변경하고 컴파일러가

B)를 사용하여 반사를 기대하고 가능하면 더 나은이를 방지 (런타임 작업을 사용하는 유형을 알려 :

우리가 두 가지 옵션이 작동하게하려면 제 3 자 라이브러리와 함께 작업 할 때 유용 할 수 있습니다).

A - 인터페이스 솔루션 :

public interface IMyInterface 
{ 
    int Id {get; set;} 
} 

public void Test<T>(List<T> rEntity) where T : IMyInterface 
{ 
    object id = 1; 
    var result = rEntity.Where(x => x.id == id); 
} 

B - 반사 솔루션 :

public void Test<T>(List<T> rEntity) 
{ 
    var idProp = typeof(T).GetProperty("Id"); 
    if(idProp != null) 
    { 
     object id = 1; 
     var result = rEntity.Where(x => idProp.GetValue(x).Equals(id)); 
    } 
} 
+0

에 정의 된 클래스입니다. Fabjan에게 감사드립니다. 시간을 많이 아끼 셨습니다. 반사 솔루션이 나를 위해 일하고있다. 다시 한번 감사드립니다. –

1

당신은 대부분의 ID 속성이 기본 클래스를 정의하고 T가 기본 클래스에서 상속 할 수 최대량.

public class BaseClass{ 
public object ID; 
} 

하고이 같은 함수를 변경할 수 있습니다

public void Test<T>(List<T> rEntity) where T : BaseClass 
{ 
    object id = 1; 
    var result = rEntity.Where(x => x.id == id); 
}