2009-11-24 100 views
3

我目前有一個類,它使用KeyValuePairList以Key = track,Value = artist的格式存儲軌道集合。從列表返回一個匹配<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>)的集合,因此,我通過比較臨時列表創建此時,相應類型的新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;使用System.Linq的 ; using System.Text;

命名空間CDCollection { 公共類CD { #地區字段 私人只讀字符串_artist; private readonly string _album; private List _track = new List(); #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;使用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 
} 

}

我有嚴格的規定,這意味着我必須從CD繼承創建我CompilationCD以及因爲使用列表>我的曲目集合,它需要同時擁有曲目和藝術家。瘋狂我知道=/

此外,我必須存儲CD類型列表中的所有類型的CD(列表)。

+1

您應該考慮使用運算符'is'而不是比較'GetType()'的返回值。它既快又短,並且在擴展性方面表現更好(例如,如果你以後從'CompilationCD'派生出一些類)。 – 2009-11-24 23:04:35

回答

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"); 
} 

你不能投了CompilationCDKeyValuePair<string, string>,所以我們直接使用CompilationCD類。我們可以將搜索軌道列表的責任移交給System.Linq提供的IEnumerable<T>擴展方法,這使得此方法非常簡單。

+0

我已經添加了CD和CompilationCD的類=] – 2009-11-25 13:05:08

+0

您使用的是哪個版本的.Net框架?根據LINQ是否可用,「標準」習語存在差異。 – Dathan 2009-11-25 17:12:15

+0

我正在使用.Net 3.5 – 2009-11-28 22:56:22

5

爲什麼不使用字典?它們是關鍵值對的列表,但通過密鑰提供了方便的訪問。

+0

當然,我不相信我沒有想到這一點。 謝謝! – 2009-11-24 22:49:38

+0

嘗試實施字典後,事實證明它有可能會破壞太多。 – 2009-11-24 23:01:20

+0

你是什麼意思,「打破」?謹慎闡述? – McKay 2009-11-24 23:13:10

0

這是因爲tempComCols將返回CD而不是KeyValuePair<string, string>

0

List不含KeyValuePairs,所以你不能循環通過它,如果它沒有。嘗試是這樣的:

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

但作爲麥凱說,如果你的CD類做什麼,但封裝一個KeyValuePair,一個Dictionary就好辦多了。

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)得到CompilationCDSystem.Type對象;你不需要撥打GetType()

0
  1. 你可以使用:

    {cd is CompilationCD}; 
    

    代替

    { return cd.GetType() == temp.GetType(); }); 
    
  2. ,如果我理解正確的CD是某種解釋的,你可以重寫功能:

    public CompilationCD FindTrackInComCD(string track) 
    { 
        return (CompilationCD)_cdCollection.Find(delegate(CD cd) 
        { return (cd is CompilationCD) && (cd.Contains(track))}); 
    } 
    
相關問題