2009-11-24 7 views
3

에서 일치 항목 반환 나는 List과 함께 KeyValuePair을 사용하는 클래스를 사용하여 Key = track, Value = artist 형식으로 트랙 모음을 저장합니다.List <KeyValuePair <string, string >>

특정 트랙을 검색하는 방법을 제공하고 일치하는 항목이 있으면 일치하는 전체 CD를 반환합니다. 이것은 지금까지 내 시도

:

public CompilationCD FindTrackInComCD(string track) 
{ 
    CompilationCD temp = new CompilationCD(); 

    List<CD> tempComCols = _cdCollection.FindAll(delegate(CD cd) 
    { return cd.GetType() == temp.GetType(); }); 

    foreach (KeyValuePair<string, string> comCD in tempComCols) 
    { 
     if (comCD.Key.Contains(track)) 
     { 
      return comCD; 
     } 
    } 

    throw new ArgumentException("No matches found"); 
} 

내가 CD를 유형 CD (List<CD>)의 컬렉션을 가지고 그러므로 나는 임시 목록과 비교하여 appropiate 형태의 새로운 List<>을 만들 수 있습니다.

나는 다음과 같은 오류를 얻을 컴파일 할 때 :

Cannot convert type 'CDCollection.CD' to System.Collections.Generic.KeyValuePair<string,string>' 

Cannot implicitly convert type 'System.Collections.Generic.KeyValuePair<string,string>' 

이 나는했습니다 하나에 비슷한 질문처럼 보이는위한

죄송합니다 (CDCollection 내 프로젝트 네임 스페이스 및 CD/CompilationCD있는 클래스이다) 이전에 물었다. 나는 이전에 주어진 방법을 사용하려고 노력했으나 조금 난처한 상태였습니다. List<> 또는 KeyValuePair을 자주 사용하지 않았습니다.

는 CD 클래스입니다 :

using System; 

은 System.Collections를 사용하는; using System.Collections.Generic; using System.Linq; using System.Text;

네임 스페이스 CDCollection { 공용 클래스 CD { # 지역 필드 개인 읽기 전용 문자열 _artist; private 읽기 전용 문자열 _album; 비공개 목록 _track = 새 목록(); #endregion

#region Constructors 
    public CD() 
    { 
     _artist = ""; 
     _album = ""; 
     _track = null; 
    } 

    public CD(string albumName) 
    { 
     _album = albumName; 
    } 

    public CD(string artistName, string albumName) 
    { 
     _artist = artistName; 
     _album = albumName; 
    } 

    #endregion 

    #region Properties 
    /// <summary> 
    /// Get/Set Artist Name 
    /// </summary> 
    public virtual string Artist 
    { 
     get 
     { 
      return _artist; 
     } 
     set 
     { 
      value = _artist; 
     } 
    } 

    /// <summary> 
    /// Get/Set Album 
    /// </summary> 
    public string Album 
    { 
     get 
     { 
      return _album; 
     } 
     set 
     { 
      value = _album; 
     } 
    } 

    /// <summary> 
    /// Get/Set Track Name 
    /// </summary> 
    public virtual List<string> Track 
    { 
     get 
     { 
      return _track; 
     } 
     set 
     { 
      value = _track; 
     } 
    } 

    #endregion 

    #region ToString() 
    /// <summary> 
    /// Custom ToString() Method 
    /// </summary> 
    /// <returns></returns> 
    public override string ToString() 
    { 
     //Create new StringBuilder object 
     StringBuilder sb = new StringBuilder(); 

     sb.Append("Artist Name"); 

     //Display error if Artist is not available 
     if (_artist == null || _artist == "") 
     { 
      sb.Append("\nNo Artist Entered"); 
     } 
     else 
     { 
      sb.Append("\n" + this._artist); 
     } 

     sb.Append("\n"); 
     sb.Append("\nAlbum Name"); 

     //Display error if Album is not available 
     if (_album == null || _album == "") 
     { 
      sb.Append("\nNo Album Entered"); 
     } 
     else 
     { 
      sb.Append("\n" + this._album); 
     } 

     sb.Append("\n"); 
     sb.Append("\nTrack Name"); 
     sb.Append("\n"); 

     //Iterate through all tracks stored in list 
     foreach (string trackName in _track) 
     { 
      //Print each artist 
      sb.Append("\n" + trackName); 
     } 

     sb.Append("\nEnd of CD Record........."); 

     return sb.ToString(); 
    } 

    #endregion 
} 

}

이것은 CompilationCD 클래스입니다 :

using System; 

System.Collections.Generic를 사용하여; using System.Linq; using System.Text;

네임 스페이스 CDCollection { 공용 클래스 CompilationCD : CD { # 지역 필드

private readonly string _artist; 
    private readonly string _album; 
    private List<KeyValuePair<string,string>> _tracks = new List<KeyValuePair<string,string>>(); 

    //List<KeyValuePair> Reference. 
    //http://msdn.microsoft.com/en-us/library/6sh2ey19(VS.85).aspx 

    #endregion 

    #region Constructors 

    public CompilationCD() 
    { 
     _album = ""; 
     _artist = "Various Artists"; 
    } 

    public CompilationCD(string albumName):base(albumName) 
    { 
     _album = albumName; 
     _artist = "Various Artists"; 
    } 

    #endregion 

    public void AddTracks(string track, string artist) 
    { 
     _tracks.Add(new KeyValuePair<string, string>(track, artist)); 
    } 

    #region Properties 

    public override string Artist 
    { 
     get 
     { 
      return this._artist; 
     } 
    } 

    public new List<KeyValuePair<string,string>> Track 
    { 
     get 
     { 
      return _tracks; 
     } 
     set 
     { 
      _tracks = value; 
     } 
    } 


    #endregion 

    #region ToString() 

    //TEST 
    public override string ToString() 
    { 
     //Create new StringBuilder object 
     StringBuilder sb = new StringBuilder(); 

     sb.Append("Artist Name"); 

     //Display error if Artist is not available 
     if (_artist == null || _artist == "") 
     { 
      sb.Append("\nNo Artist Entered"); 
     } 
     else 
     { 
      sb.Append("\n" + this._artist); 
     } 

     sb.Append("\n"); 
     sb.Append("\nAlbum Name"); 

     //Display error if Album is not available 
     if (base.Album == null || base.Album == "") 
     { 
      sb.Append("\nNo Album Entered"); 
     } 
     else 
     { 
      sb.Append("\n" + base.Album); 
     } 

     sb.Append("\n"); 
     sb.Append("\nTrack Name"); 
     sb.Append("\n"); 

     ////Iterate through all tracks stored in list 
     //foreach (string trackName in base.Track) 
     //{ 
     // //Print each artist 
     // sb.Append("\n" + trackName); 
     //} 

     for(int i = 0; i <= _tracks.Count; i++) 
     { 
      string track = _tracks[i].Key; 
      string artist = _tracks[i].Value; 

      sb.Append("\nTrack"); 
      sb.Append(track); 
      sb.Append("\nArtist"); 
      sb.Append(artist); 
     } 

     sb.Append("\nEnd of Compilation CD Record........."); 

     return sb.ToString(); 
    } 

    #endregion 
} 

}

I가 난 내 CompilationCD을뿐만 아니라 만들 CD에서 상속해야 의미 엄격한 규칙 내 트랙 컬렉션에 List>를 사용하면 트랙과 아티스트를 모두 보유해야합니다. Crazy i know =/

또한 모든 유형의 CD를 CD (목록) 유형 목록에 저장해야합니다.

+1

'GetType()'의 반환 값을 비교하는 대신'is' 연산자를 사용해야합니다. 더 빠르고, 짧으며, 확장 성 (예 :.나중에'CompilationCD'에서 어떤 클래스를 파생 시킨다면). –

답변

2

문제는 foreach 루프에 있습니다. tempComColsList<CD>이지만 comCDKeyValuePair<string, string>입니다. 따라서 루프가 잘못된 유형 변환을 초래합니다.

불행히도 CD 클래스 (인터페이스?)가 어떤 모양인지 모르기 때문에 속성에 대한 수정을 제안 할 수 없습니다.

편집 : 다음은 아마도 더 나은 방법의 버전 (하지만, 나는 제대로 디버깅하지 않은 경우)입니다 :

public CompilationCD FindTrackInComCD(string track) 
{ 
    CompilationCD temp = new CompilationCD(); 

    temp = _cdCollection.Where(cd => cd is CompilationCD) 
         .Cast<CompilationCD>() 
         .Where(com_cd => com_cd.Tracks.ContainsKey(track)) 
         .FirstOrDefault(); 

    if (temp != null) 
     return temp; 
    else throw new ArgumentException("No matches found"); 
} 

당신은 KeyValuePair<string, string>CompilationCD 캐스팅 할 수없는, 그래서 우리 CompilationCD 클래스를 직접 사용하십시오. System.Linq에 의해 제공되는 IEnumerable<T> 확장 메서드로 트랙 목록을 검색하는 책임을 전달할 수 있으므로이 방법이 매우 쉽습니다.

+0

CD 및 CompilationCD에 대한 클래스를 추가했습니다.] –

+0

사용중인 .NET Framework 버전은 무엇입니까? LINQ의 사용 가능 여부에 따라 "표준"관용어에 차이가 있습니다. – Dathan

+0

.Net 3.5를 사용하고 있습니다. –

5

왜 사전을 사용하지 않습니까?키 값 쌍 목록이지만 키를 통해 쉽게 액세스 할 수 있습니다. tempComColsCD를 반환하지 KeyValuePair<string, string>

+0

물론, 나는 그 생각을하지 않았다는 것을 믿을 수 없다. 감사합니다. –

+0

사전을 구현하려고 시도한 후에는 너무 많이 손상 될 가능성이 있습니다. –

+0

"깨는"무엇을 의미합니까? 정교한 케어? – McKay

0

,이다 당신이 그것을 통해 루프가했던 것처럼 할 수 없도록.

foreach (CD comCD in tempComCols) 
{ 
    if (comCD.MyKeyValueProp.Key.Contains(track)) 
    { 
     return comCD; 
    } 
} 

을하지만 맥케이가 말한대로 당신의 CD 클래스는 아무것도하지 않습니다하지만 KeyValuePair을 캡슐화하는 경우,하는 Dictionary 훨씬 쉬울 것 :이 같은 것을보십시오.

0

귀하의 ListKeyValuePairs 포함되어 있지 않기 때문에

0

tempComCols는 CD 항목의 목록은 다음과 같습니다 List<CD> tempComCols ... 당신은 유형을 IEnumerable 뭔가 반복 할 : foreach (KeyValuePair<string, string> comCD in tempComCols)

0

당신은 List<CD>을 열거하고 KeyValuePair<string, string>에 할당됩니다.

당신은 다음과 같은 C# 3에 LINQ를 사용하여 방법을 다시 작성할 수 있습니다 : 그런데

public CompilationCD FindTrackInComCD(string track) { 
    return _cdCollection.OfType<CompilationCD>().FirstOrDefault(cd => cd.Name.Contains(track, StringComparison.CurrentCultureIgnoreCase)); 
} 

을, 당신은 typeof(CompilationCD)를 작성하여 CompilationCD에 대한 System.Type 개체를 얻을 수 있습니다; GetType()으로 전화 할 필요가 없습니다.

0
  1. 사용할 수 :

    : 내가 제대로 이해한다면 대신

    { return cd.GetType() == temp.GetType(); }); 
    
  2. {cd is CompilationCD}; 
    

    및 CD 사전의 어떤 종류의, 당신은 기능을 다시 작성할 수 있습니다

    public CompilationCD FindTrackInComCD(string track) 
    { 
        return (CompilationCD)_cdCollection.Find(delegate(CD cd) 
        { return (cd is CompilationCD) && (cd.Contains(track))}); 
    } 
    
관련 문제