2014-12-21 3 views
2

:C#으로 내 선택의 변수에 포인팅 나는 다음을 수행하려고 해요

bool Has_Unique_Index<T>(Indexed<T> obj) 
{ 
    byte type = Verify_Type<T>(obj); 
    List<Indexed<T>> list; 

    switch (type) 
    { 
     case 0: list = DataSource.Clients; break; 
     case 1: list = DataSource.Rentals; break; 
     case 2: list = DataSource.Cars; break; 
     case 3: list = DataSource.Faults; break; 
    } 

    foreach (var i in list) 
    { 
     if (i.Index == obj.Index) 
      return false; 
    } 

    return true; 
} 

(그들없이 사용 삼각형 브래킷은 HTML 무효로 사라지고 방법을 알아낼 수 없습니다) :

그러나 컴파일러는 DataSource.x를 List (Indexed (T)) 형식으로 변환 할 수 없다고 알려줍니다.

Verify_Type (T) (obj)는 T가 List의 4 가지 옵션 중 하나임을 확인하므로 List (Indexed (T))는 괜찮을 것입니다.

  • C#에서 switch 문 (또는 다른 방법)을 사용하여 내가 선택한 변수를 어떻게 가리킬 수 있습니까?

EDIT : DataSource.x는 List (Indexed (T)) 유형입니다.

EDIT2 : 사람들이 지적했듯이 실제로 소스는 List (Indexed (SOMECONCRETETYPE)) 유형입니다.

답변

1

당신은 속성을 캐스팅해야합니다. 나는 이런 식으로 한 번만 할 것입니다 :

bool Has_Unique_Index<T>(Indexed<T> obj) 
{ 
    byte type = Verify_Type<T>(obj); 
    object dataSource = null; 

    switch (type) 
    { 
     case 0: dataSource = DataSource.Clients; break; 
     case 1: dataSource = DataSource.Rentals; break; 
     case 2: dataSource = DataSource.Cars; break; 
     case 3: dataSource = DataSource.Faults; break; 
     default: return false; // or throw an exception etc. 
    } 

    bool result = (dataSource as List<Indexed<T>>).Any(x => x.Index == obj.Index); 
    return result; 
} 
+0

새로운 조건으로 반복해서 같은 조건을 쓰는 것을 싫어합니다. 그래도 JesseJames의 대답은 변수를 죽일 수있었습니다 :) – user2962533

+1

OP 살인 변수가 마음에 들면 변수에 _need_를 입력하지 않아도됩니다. switch (Verify_Type (obj)) : –

+0

@StephenKennedy 너무 많은 변수를 줄이는 것도 좋은 습관이 아닙니다 ... 조만간 디버깅하는 동안 다시 필요합니다 ;-) 그래서 내가 결과 헬퍼 변수. – t3chb0t

1

T는 제네릭 형식이므로 List<Indexed<T>>의 DataSource.Cars가없는 것 같지만 List<Indexed<Car>>입니다. T가 예를 들어 T에 캐스팅 될 수없는 것은 물론입니다. 고객. 각 목록 할당에 List<Indexed<T>>에 명시 적 형변환을 추가해 봅시다.

2

(List<Index<T>>)으로 명시 적으로 캐스팅하여 컴파일 오류를 해결할 수 있습니다 (Jan Zahradník).

case 0: list = (List<Index<T>>)DataSource.Clients.ToList(); break; 

또는 단순화 방법 :

bool Has_Unique_Index<T>(Indexed<T> obj) 
{ 
    byte type = Verify_Type<T>(obj); 

    switch (type) 
    { 
     case 0: return !DataSource.Clients.Any(r=> r.Index == obj.Index); break; 
     case 1: return !DataSource.Rentals.Any(r=> r.Index == obj.Index); break; 
     case 2: return !DataSource.Cars.Any(r=> r.Index == obj.Index); break; 
     case 3: return !DataSource.Faults.Any(r=> r.Index == obj.Index); break; 
    } 

    throw new Exception("unknown type: " + type); 
} 
+0

캐스팅이 작동하지 않는 것처럼 보입니다. 삭제 된 게시물의 형식은 다음과 같습니다. 나는 가볍게 읽을 수있는 솔루션을 사용하여 객체로 '목록'을 만들어 나중에 List (Indexed (T))로 캐스팅했지만이 솔루션은 여분의 객체를 모두 제거합니다. Has_Unique_Index에 지정된 유형이 유효하지 않은 경우 Verify_Type이 이미 예외를 throw합니다. 코드에서 명확하게 설명해야합니까? – user2962533

+0

@ user2962533 내 대답을 말씀하시는 것 같습니까? 히트 삭제 edit indead of :-) – t3chb0t

+0

그'break' 문은 불필요하며 컴파일러 경고를 일으킬 것입니다 – BrokenGlass

1

컴파일이 실패하는 이유는 질문에서의 편집이 약간 잘못된 이유와 같습니다. DataSource.x 개체의 유형은 List<Indexed<T>>이지만 사실은 유형이 List<Indexed<SOMECONCRETETYPE>>입니다.

편집은 DataSource.x 객체의 적어도 세 T대상하지 실패이기 때문에 (즉, 그들은 일반이 아니므 이미 콘크리트있는 기본 유형을 변경했다).

님의 List<Indexed<T>>에 '캐스팅'할 수

bool Has_Unique_Index<T>(Indexed<T> obj) 
{ 
    List<Indexed<T>> list == null; 

    switch (Verify_Type<T>(obj)) 
    { 
     case 0: list = DataSource.Clients as List<Indexed<T>>; break; 
     case 1: list = DataSource.Rentals as List<Indexed<T>>; break; 
     case 2: list = DataSource.Cars as List<Indexed<T>>; break; 
     case 3: list = DataSource.Faults as List<Indexed<T>>; break; 
    } 

MSDN :는 " as 연산자는 캐스팅 작업 비슷하지만, 반환 예외를 발생시키는 대신 NULL로 변환이 가능하지 않은 경우.."

던져리스트가 null의 경우 (유형 범위를 벗어났습니다 또는 as는 null을 반환) : 우리는 대신 foreach 루프의 IEnumerable.All을 사용할 수 있습니다

if (list == null) 
     throw SomeException(); 

을 : 물론

return list.All(i => i.Index != obj.Index); 
} 

당신이 할 수있는 Jesse James의 답변에서 더 짧은 코드를 선택하면 캐스팅/변환을 모두 피할 수 있습니다.

관련 문제