2014-12-10 2 views
2

나는 다음과 같은 라인을 따라 일반적인 방법을 쓰고 싶은 :단일 일반 솔루션?

public IEnumerable<T> S<T> (List<T> source) 
{ 
    //dosomething with source 
    if (someCondition) 
     yield return null; 
    else 
     yield return someNonNullItem; 
} 

T가 값 형식 (예를 들어, INT), null 허용 유형 (? 예를 들어, int)를, 또는 심판 유형 (예를 들어, 문자열)이 될 수 있습니다. 세 가지 경우 모두 null 값을 반환 할 수 있어야합니다.

// dosomething 블록은 꽤 일반적이며 주변의 물건을 이동시키는 것을 포함하며 수정하지 않고 모든 유형과 함께 사용할 수 있습니다. 비슷하게, (someCondition) boolean check는 타입 종속성을 가지지 않는다.

몇 가지 고려 사항 : 나는 T는 nullable이 아닌 값 형식 (T는 INT가 작동하지 않을 것입니다 예를 들어, 기본 (T))은 기본 (T)를 사용할 수 없습니다

  1. . null의 명시적인 표현이 필요합니다.
  2. T에서 T로 변환하고 싶지 않습니까? 소스 목록이 꽤 오래있을 수 있기 때문에 피할 수 있다면 (수백만 개의 항목).

현재 3 가지 기능을 작성해야하며 그 중 하나는 다른 이름을 사용해야합니다 (유형 제약이 메소드 서명의 일부로 간주되지 않기 때문에). 세 가지 기능은 동일한 몸체를 가지고 있습니다 (간결성을 위해 표시되지 않음).

public IEnumerable<T?> S<T>(List <T> source) where T:struct 
    { 
    } 

    public IEnumerable<T?> S<T>(List <T?> source) where T : struct 
    { 
    } 

    public IEnumerable<T> S4Ref<T>(List <T> source) where T : class 
    { 
    } 

처음 두 메서드에서 Nullable을 반환 할 수 있도록 T : struct 제약 조건이 필요합니다. 세 번째 방법 : (a) 첫 번째 방법과의 충돌을 피하기 위해 새 이름 인 S4Ref가 필요합니다. (b) null을 반환하려면 T : class 제약 조건이 필요합니다.

사실 내가 작성해야하는 수많은 S 메소드가 있습니다. 위의 방법을 따르는 경우 각각에 대해 세 가지 버전을 작성해야합니다.

  1. 이 작업을 수행 하나의 일반적인 기능을 가지고 할 수있는 방법이 있나요 : 나는 또한 목록에 대한 확장 방법

    질문으로 만들어 놓을거야? 아니면 적어도 3에서 2 가지 방법으로 줄이십니까?

  2. 그렇지 않은 경우 함수 본문에서 중복을 제거하는 가장 좋은 방법은 무엇입니까?

현재이 문제를 해결하기 위해 T4 템플릿을 사용하고 있습니다.

+0

'T'가'int' (** not **'int?')이면'null'을 반환 할 수 없습니다. –

+2

우선 null 값을 생성하는 디자인을 처음부터 재평가하는 것이 좋습니다. 또는 최소한 메소드의 호출자가 nullable 형식을 전달해야하며 변환을 nullable이 아닌 상태로 유지해야합니다. 그들의 책임을 무시할 수있다. – Servy

+1

두 가지 방법보다 좋을 것 같지 않습니다. 기본적으로 'IEnumerable '이고, 'IEnumerable '는 'T'에 제약이 없습니다. 이름이 다른 경우 호출자가 nullable 값 유형으로 호출하지 않도록 "신뢰"합니까? –

답변

0

당신은 상충되는 제약 조건으로 스스로를 설정했습니다. 문제 정의에서 값 유형 (즉, int)에서 작동하지만 null 허용 유형으로 변환하지 않고 null을 반환 할 수있는 함수를 원한다고 가정합니다. 디자인 패러다임으로서, 나는 존재하지 않는 무언가를 포함하는 것들의 컬렉션을 기대하지 않습니다. 그래, 내가 그랬어. 나에게 null 항목을 반환하는 것은 존재하지 않는다는 것을 의미하지만 아직 null을 반환합니다. 함수 S의 목적이 항목을 필터링하는 것이라면 일치하지 않는 항목을 건너 뛰고 다음 항목을 반환하는 것이 좋습니다.foreach 문은 다음과 같이 경우에도, 즉

List<int> myList = .... // somehow fill the list 
    foreach(int element in S(myList)) 
    { 
     // do something with the int element. What should I expect to do with a null 
     // even if you could return one? The only thing I could reasonable do here is 
     // skip it. I have no idea which element of myList the null corresponds to 

    } 

:

foreach(int? element in S(myList)) 

나는 아직도 붙어

예를 들어,는 IEnumerable의 일반적인 용도는 다음과 같습니다 코드 요소에 null 값을 사용하여 수행 할 작업. myList의 어떤 요소가 함수 S의 널을 유발했는지 알 수있는 문맥은 아직 없습니다.

+0

의견에 감사드립니다. 명확히하기 위해 : 입력리스트 을 처리하기 전에리스트 으로 변환하고 싶지 않습니다. 입력이 처리 된 후 값이 누락됩니다. – Fenchurch