2017-05-28 68 views
0

我想在我的代碼中集成ienumerable,以便它是隻讀的,但我不知道在哪裏可能實現它。到目前爲止,我還沒有在互聯網上找到任何可能解決我的問題的解決方案。截至目前,我只使用List,並希望在我的代碼中集成ienumerable。另外,如果您發現錯誤的編碼習慣,請隨時提出建議。如何返回一個只讀的IEnumerable <T>而不是一個列表<T>

下面是代碼:

public static List<GuitarItems> GetGuitarItems(string itemCategory) 
{ 
    List<GuitarItems> list = new List<GuitarItems>(); 
    string query = string.Format("SELECT * FROM guitarItems WHERE brand LIKE @brand"); 

    try 
    { 
     conn1.Open(); 
     command1.CommandText = query; 
     command1.Parameters.Add(new SqlParameter("brand", itemCategory)); 
     SqlDataReader reader = command1.ExecuteReader(); 

     while (reader.Read()) 
     { 
      int id = reader.GetInt32(0); 
      string type = reader.GetString(1); 
      string brand = reader.GetString(2); 
      string model = reader.GetString(3); 
      double price = reader.GetDouble(4); 
      string itemimage1 = reader.GetString(5); 
      string itemimage2 = reader.GetString(6); 
      string description = reader.GetString(7); 
      string necktype = reader.GetString(8); 
      string body = reader.GetString(9); 
      string fretboard = reader.GetString(10); 
      string fret = reader.GetString(11); 
      string bridge = reader.GetString(12); 
      string neckpickup = reader.GetString(13); 
      string bridgepickup = reader.GetString(14); 
      string hardwarecolor = reader.GetString(15); 

      GuitarItems gItems = new GuitarItems(id, type, brand, model, price, itemimage1, itemimage2, description, necktype, body, 
       fretboard, fret, bridge, neckpickup, bridgepickup, hardwarecolor); 
      list.Add(gItems); 
     } 
    } 
    finally 
    { 
     conn1.Close(); 
     command1.Parameters.Clear(); 
    } 

    return list; 
} 

然後這裏是另一個代碼:

private void FillPage() 
{ 
    List<GuitarItems> itemList = new List<GuitarItems>(); 
    List<string> itemListPage = new List<string>(); 

    itemList = ConnectionClassGuitarItems.GetGuitarItems(brandType); 

    StringBuilder sb = new StringBuilder(); 

    foreach (GuitarItems gList in itemList) 
    { 
     itemListPage.Add("GuitarItemsIbanezDetails" + (x + 1) + ".aspx"); 

     sb.Append(
       string.Format(
        @" 
        <div class='one-two'> 
         <a href='{3}' runat="'server'"><img runat="'server'" src='{0}'/></a> 
         <div class='content'> 
          <div id='label'>{1} {2}</div> 
         </div> 

       </div>", gList.ItemImage1, gList.Brand, gList.Model, itemListPage[x])); 

     x++; 

    } 


    lblOutput.Text = sb.ToString(); 

} 
+1

您有一個XSS漏洞。而且你不能像這樣構建服務器端控件。你應該使用數據綁定。 – SLaks

+0

@SLaks - 如果我添加了一個代碼,如果有腳本標記,它將取消用戶的輸入?這將有助於消除XSS漏洞? –

+0

不需要。您需要了解_encoding_。 – SLaks

回答

2

技術上a List<T>IEnumerable<T>,但我理解你的意思。如果您返回List<T>那麼該列表可能會被修改。你想要返回可以傳遞的東西,而不需要任何人修改其內容。

有兩件事你可以做到這一點。第一個可能是你所需要的。

首先,改變這一

public static List<GuitarItems> GetGuitarItems(string itemCategory) 

這樣:

public static IReadOnlyList<GuitarItems> GetGuitarItems(string itemCategory) 

如果你這樣做,沒有別的,函數的返回值將被強制轉換爲IReadOnlyList<T>。該界面不允許修改列表。 (它不會阻止更改列表中項目的屬性 - 這完全是另外一回事。)

List<T>可以轉換爲IReadOnlyList<T>,因此您不必更改方法中的其他任何內容。您可以像現在一樣創建List<GuitarItems>,但只需更改函數的返回類型即可將其作爲IReadOnlyList<GuitarItems>返回。

這可能會完成你所需要的。但是,如果您特別擔心修改列表內容的其他內容,則可以繼續。

例如,即使從集合返回的項目被轉換爲IReadOnlyList<GuitarItems>,有人仍然可以這樣做:

var readonlyList = GetGuitarItems("category"); // returns IReadOnlyList<GuitarItems> 
var list = readonlyList as List<GuitarItems>; 
list.Clear(); // Oh, no - they've modified the list anyway! 

這將起作用,因爲該項目從函數返回實際上是一個列表。沒有人應該試圖將它作爲別的東西 - 他們應該使用你正在返回的類型。但出於某種奇怪的原因,有人可以這樣做。

對於額外的預防你可以改變你的函數從該回歸:

return list; 

要這樣:

return list.AsReadOnly(); 

結果是,現在你沒有返回List<GuitarItems>塑像作爲IReadOnlyList<GuitarItems>AsReadOnly()創建了一個新的集合,一個ReadOnlyCollection<GuitarItems>並且將作爲作爲IReadOnlyList<GuitarItems>。現在,不僅返回的類型表明該列表不能被修改,但它確實無法修改,因爲它是隻讀集合。

查看它的一個好方法是該方法的返回值應表明消費者對它的期望。如果您希望他們收到他們不應修改的列表,請返回IReadOnlyList<T>


一個相關的問題是,你是否應該返回IEnumerable<T>IReadOnlyList<T>IEnumerable<T>更通用,也不代表可以更改的列表。你會看到它更經常使用。區別在於IEnumerable<T>可能代表執行的查詢。如果要枚舉的項目不止枚舉一次,則可能導致多次執行查詢。

在你上面的例子,如果你改變了List<GuitarItems>IEnumerable<GuitarItems>你還真返回List<GuitarItems>,所以多次枚舉列表不多次執行查詢。但是,誰現在有一個IEnumerable<GuitarItems>消費者無法知道這一點,所以他們會想要做這樣的事情:

var items = GetGuitarItems("category").ToList(); 

,以確保查詢被執行一次投入,他們可以列舉的清單儘可能多的次數。

返回IReadOnlyList<GuitarItems>讓他們知道他們擁有的絕對是一個列表,而不是每次枚舉時都會被查詢的東西。

如果您使用Resharper,這將變得明顯。如果你有一個IEnumerable<T>並且你不止一次地列舉它,它會警告你。該項目可能確實是一個列表或數組,但你不知道。

+0

順便說一下,我有一個問題..在第二個代碼中,我已經在private void FillPage()方法中提供了上面的代碼。爲了使它適用於您的解決方案,我更改了列表 itemList = new List ();進入IReadOnlyList itemList ;.我做對了嗎?因爲它似乎不工作,如果我嘗試這樣做 - > IReadOnlyList itemList = new IReadOnlyList (); –

0

你想實現什麼?

List<T>它已經是一個IEnumerable<T>,因爲它實現IEnumerable<T>接口,這樣你可以把你的List<T>IEnumerable<T>例如,在方法的參數。

相關問題