2014-09-30 126 views
0

所以我有一個CreditCard類,它具有一些屬性,其中一個用於卡號作爲字符串(public string Number { get; set; })。我將CreditCard對象存儲在具有變量列表(private List<CreditCard> cclist = new List<CreditCard>();)的CreditCardList類中。我希望能夠通過首先對List進行排序,然後使用列表中的BinarySearch方法來檢索CreditCard的卡號。我也想通過傳遞一個數字的字符串索引器來搜索BinarySearch方法,以及一個比較器(如果我需要的話)。List <T>使用字符串索引器的BinarySearch

這是我到目前爲止的方法來獲得CreditCard匹配的數字,但Visual Studio 2013給我一個錯誤的行:int index = cclist.BinarySearch(cclist[input], new CreditCardComparer());「最好的重載方法匹配'System.Collections.Generic.List .this [int]'有一些無效的參數。「我認爲這是因爲我使用String索引器錯誤或什麼。

public List<CreditCard> GetCardByNumber (string input) 
{ 
    List<CreditCard> tempList = new List<CreditCard>(); 

    // save the current unsorted list to a temporary list to revert back to after sorting 
    List<CreditCard> originalList = new List<CreditCard>(cclist.Capacity); 

    for (int i = 0; i < cclist.Capacity; i++) 
    { 
     originalList[i] = cclist[i]; 
    } 

    // begin sorting for binary search of card number 
    cclist.Sort(); 

    int index = cclist.BinarySearch(cclist[input], new CreditCardComparer()); 

    if (index < 0) 
    { 
     tempList.Add(cclist[input]); 
    } 

    // revert back to the original unsorted list 
    for (int i = 0; i < originalList.Capacity; i++) 
    { 
     cclist[i] = originalList[i]; 
    } 

    // return the found credit card matching the specified number 
    return tempList; 
}// end GetCardByNumber (string input) 

這裏是我的int和字符串索引:

public CreditCard this[int i] 
{ 
    get 
    { 
     if (i < 0 || i >= cclist.Count) 
     { 
      throw new ArgumentOutOfRangeException("index " + i + " does not exist"); 
     } 

     return cclist[i]; 
    } 
    set 
    { 
     if (i < 0 || i >= cclist.Count) 
     { 
      throw new ArgumentOutOfRangeException("index " + i + " does not exist"); 
     } 

     cclist[i] = value; 
     saveNeeded = true; 
    } 
}// end CreditCard this[int i] 

public CreditCard this[string input] 
{ 
    get 
    { 
     foreach (CreditCard cc in cclist) 
     { 
      if (cc.Number == input) 
      { 
       return cc; 
      } 
     } 

     return null; 
    } 
}// end CreditCard this[string number] 

這裏是我的比較器類:

public class CreditCardComparer : IComparer<CreditCard> 
{ 
    public override int Compare(CreditCard x, CreditCard y) 
    { 
     return x.Number.CompareTo(y.Number); 
    } 
}// end CreditCardComparer : IComparer<CreditCard> 

最後,這裏是我的名單排序,什麼不是必需品...

class CreditCard : IEquatable<CreditCard>, IComparable<CreditCard> 
{ 
    public bool Equals (CreditCard other) 
    { 
     if (this.Number == other.Number) 
     { 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    }// end Equals(CreditCard other) 

    public int CompareTo(CreditCard other) 
    { 
     return Number.CompareTo(other.Number); 
    }// end CompareTo(CreditCard other) 
} 

是否真的有可能做我正在嘗試,即發送一個字符串索引器,返回基於字符串的CreditCard對象到List的BinarySearch方法?

此外,如有必要,我可以提供更多的代碼,但是我覺得這有點多。

+1

你可以解決你所有的問題**不存儲* *信用卡信息開始,我不知道這是否合法允許。 – user2711965 2014-09-30 17:58:00

+2

這只是一個學校的示例練習。這裏沒有真正的信息。 :) – user48743 2014-09-30 18:03:00

+1

這似乎瘋狂過度設計。必須是學校項目。 – 2014-09-30 18:04:47

回答

0

您的GetCardByNumber方法中存在一些缺陷。首先是該方法返回一個完整的列表,而不是單個的CreditCard,這違背了方法名稱。其次,甚至沒有必要的二進制搜索,因爲你在字符串索引做搜索第一:

public CreditCard this[string input] 
{ 
    get 
    { 
     foreach (CreditCard cc in cclist) 
     { 
      if (cc.Number == input) 
      { 
       return cc; 
      } 
     } 

     return null; 
    } 
} 

至此,你已經找到你所需要的信息的信用卡式,那麼爲什麼重新搜尋,在BinarySearch中?第三,正如landoncz的回答所涵蓋的,你不能使用字符串作爲List<T>的索引。什麼你可能打算利用是如果你正在嘗試訪問實現它(這我假設你正在試圖做的類的內部索引屬性代替List<CreditCard>

CreditCardList creditCardList = new CreditCardList(); 
creditCardList["1234"]; //correct 

List<CreditCard> cclist = new List<CreditCard>(); 
cclist["1234"]; //incorrect. This is where your error is coming from. 

您GetCardByNumber法),只需使用this[index]

public class CreditCardList 
{ 
    public CreditCard this[string s] { /*Implementation*/ } 

    public CreditCard GetCard(string s) 
    { 
     return this[s]; // right here! 
    } 
} 

現在......根據你的評論,「Retrieve the CreditCard with a specified number if it exists using the BinarySearch method in List<T> in the implementation of a String indexer.」,在我看來,這樣的決定要你做的東西沿着這些路線。(要注意的事情是,我不知道你的信用卡式類的整個實現的,所以請原諒天真的實例在下面的代碼)

public class CreditCardList 
{ 
    private List<CreditCard> cclist = new List<CreditCard>(); 

    public CreditCardList() 
    { 
     //For the sake of an example, let's magically populate the list. 
     MagicallyPopulateAList(cclist); 
    } 

    public CreditCard this[string s] /* In the implementation of a String indexer... */ 
    { 
     get 
     { 
      CreditCard ccToSearchFor = new CreditCard() { Number = value }; 
      cclist.Sort(); 

      /* ...use the BinarySearch method... */ 
      int index = cclist.BinarySearch(ccToSearchFor); 

      if (index >= 0) 
       return cclist[index]; /* ...to retrieve a CreditCard. */ 
      else 
       throw new ArgumentException("Credit Card Number not found."); 
     } 
    } 
} 
+0

這看起來好像會起作用,儘管在每次查找時排序整個列表都有點過分。隨着元素添加到列表中,按排序順序維護列表會更好。 'BinarySearch'可以幫助解決這個問題,甚至還有一個MSDN文檔中的示例。 – 2014-09-30 20:19:20

+0

您的回答對我來說很重要,但我現在還有一個問題。在我單獨的驅動程序類(所有I/O都在此)中,我試圖顯示與提供的號碼匹配的卡。我使用int indexer可以很好地工作:「Console.WriteLine(cclist [n] .ToString());」並根據列表的正確索引正確顯示它。問題出在做同樣的事情,但使用字符串索引器:「Console.WriteLine(cclist [input] .ToString())」引發索引超出範圍的異常。我像上面提到的那樣實現了字符串索引器。我究竟做錯了什麼? – user48743 2014-09-30 20:32:30

+0

@BrianReischl真實。這是一個真正的「裸骨」方法,只是爲了說明問題,但是牢記始終排序列表的想法絕對不會傷害到它。 – 2014-09-30 21:22:34

1

A System.Collections.Generic.List使用int作爲索引器屬性,它不允許使用字符串。

如果你想使用一個字符串作爲你的索引器(主鍵),你應該使用Dictionary<string,CreditCard>來代替。

+0

該項目任務需要我使用列表。實際上,我們還沒有涉及Dictionary類。 – user48743 2014-09-30 18:09:55

+0

好吧,難道... – landoncz 2014-09-30 18:12:11

+0

我會在那種情況下刪除int索引器,然後 – landoncz 2014-09-30 18:30:19

相關問題