2014-08-27 84 views
0

我得出的結論可能是不可能的,但我想我會在完全放棄之前問這裏。我所尋找的是類似這樣的東西:存儲在字典中的C#「匿名」類型的列表

Dictionary<string, List<T>> FilterLists { get; set; } 

我希望能夠存儲可能需要列出的任何金額,然後可以通過一個字符串鍵「索引」來找到它們。

我需要這樣的原因是由於某些約束條件導致它必須存儲在哪裏,並且不可能將List列爲任何特定對象,因爲它無法看到我想要的對象類型放在那裏。即使我可以看到對象類型,也會降低其他項目中的可重用性,因爲在其他項目中,有人可能想要放在其中的某個項目的構建方式可能會有所不同,我試圖儘可能使其具有可重用性。

我發現了這篇文章:Declaration of Anonymous types List,但這並不完全符合我所要做的。

此外,這必須在一個接口類,所以它只是一個定義。

使用說明: 這是專門用於分頁MVC5應用程序的結果。返回結果列表,但我也希望在某些標題列中使用下拉篩選器(就像您在Excel的列篩選中看到的那樣)。

我想盡量避免使用ViewBag,因爲幾個原因。我不喜歡使用它。 我的「分頁」代碼位於一個稱爲Common的項目中,這個項目可以讓我的Web項目和我的Service項目(業務邏輯層)都可以訪問它。我正在使用的模型和ViewModel存儲在Service中,所以我不能使用Common引用服務,因爲Service已經爲用於定義將分頁的對象列表的自定義IPagedList結構引用Common。 IPagedData包含一組用於篩選,排序和分頁結果集的屬性。一個LINQ擴展(.ToPageList)被創建來促進數據上的這些操作。這個過程涉及到幾個對象,但我至少會發布IPagedData(我希望這個字典去)。

using System.Collections.Generic; 

namespace GameKeyExchange.Common.Pagination 
{ 
    public interface IPagedData 
    { 
     Dictionary<string, List<T>> FilterLists { get; set; } 

     /// <summary> 
     /// Stores pagination and sort information. 
     /// </summary> 
     PageSortCriteria Criteria { get; set; } 

     /// <summary> 
     /// Total number of subsets within the superset. 
     /// </summary> 
     int PageCount { get; } 

     /// <summary> 
     /// Total number of objects contained within the superset. 
     /// </summary> 
     int TotalItemCount { get; } 

     /// <summary> 
     /// Zero-based index of this subset within the superset. 
     /// </summary> 
     int PageIndex { get; } 

     /// <summary> 
     /// One-based index of this subset within the superset. 
     /// </summary> 
     int PageNumber { get; } 

     /// <summary> 
     /// Maximum size any individual subset. 
     /// </summary> 
     int PageSize { get; } 

     /// <summary> 
     /// Returns true if this is NOT the first subset within the superset. 
     /// </summary> 
     bool HasPreviousPage { get; } 

     /// <summary> 
     /// Returns true if this is NOT the last subset within the superset. 
     /// </summary> 
     bool HasNextPage { get; } 

     /// <summary> 
     /// Returns true if this is the first subset within the superset. 
     /// </summary> 
     bool IsFirstPage { get; } 

     /// <summary> 
     /// Returns true if this is the last subset within the superset. 
     /// </summary> 
     bool IsLastPage { get; } 
    } 
} 

的代碼實現理想的情況是這樣的,我服務:

var list = data.ClaimedKeys.Where(m => m.UserId == UserId).Select(m => new ClaimedKeysViewModel() 
{ 
    KeyTypeId = m.GameKey.GameKeyGroup.KeyTypeId, 
    PlatformId = m.GameKey.GameKeyGroup.PlatformId, 

    Value = m.GameKey.Value, 
    KeyType = m.GameKey.GameKeyGroup.KeyType.Name, 
    Game = m.GameKey.GameKeyGroup.Game.Name, 
    Platform = m.GameKey.GameKeyGroup.Platform.Name, 
    Expiration = m.GameKey.GameKeyGroup.Expiration 
}) 

list.FilterLists.Add("KeyTypeFilter", list.Select(m => new List<SelectListModel>() 
{ 
    Value = m.KeyTypeId, 
    Text = m.KeyType 
}); 

list.FilterLists.Add("PlatformFilter", list.Select(m => new List<SelectListModel>() 
{ 
    Value = m.PlatformId, 
    Text = m.Platform 
}); 

list.OrderBy(string.Format("{0} {1}", sort, order)) 
    .ToPagedList<ClaimedKeysViewModel>(pageNumber, pageSize); 

這樣一來,我可以得到的數據列表中的服務進行分頁,建立我的分頁,並且還包括任何過濾器列表的數量被髮送回控制器。控制器接收到:IPageList是數據列表,包括用於排序和過濾的這些額外屬性。他們與數據列表一起傳遞的原因是,當通過單擊標題或更改頁面時,您確切知道您處於哪個頁面以及您獲取每個頁面或度假村時的當前排序狀態。

否則,我必須對數據庫進行輔助調用才能構建過濾器並將其作爲ViewBag對象發送。另外,因爲初始視圖和刷新方法(在初始加載頁面後使用它),我必須在兩種方法中都有相同的代碼來構建列表。如果我可以在生成列表的服務方法中擁有它,那隻需在那裏完成;無論如何,這兩個控制器方法中已經調用過相同的方法。

希望能夠更好地闡明用例。

+0

向我們展示你希望如何使用** **那個。順便說一句,如果你添加一個通用參數'T'到你的界面(或者 - 放棄良好的編譯時檢查 - 如果你避免泛型 - 所有在一起 - 無類型列表,對象或動態 - 如果列表內部不同'interface')... – 2014-08-27 13:44:23

+4

'List '可以保存匿名類型,但是如果沒有反射或其他東西,你不能對它們做很多事情。 '列表'可以容納它們並允許你輸入成員,但是會將很多潛在的問題轉移到運行時。我誠實的回答?對於任何問題,這似乎是一個非常糟糕的設計/解決方案。 – 2014-08-27 13:45:18

+1

你會發現這個問題的唯一答案是添加一個類型參數到你的類/接口,正如其他人所說的。這將有助於看到你打算如何使用它。 – Brandon 2014-08-27 13:56:02

回答

0

除了使用List<object>,它可能有助於使你的界面通用:

public interface MyInterface<T> 
{ 
    Dictionary<string, List<T>> FilterLists { get; set; } 
} 
1

如果你不知道在編譯時類型T,那麼爲什麼你需要擺在首位的仿製藥?

如果你僅僅意味着在不同項目中重新使用它,然後添加一個通用的限制,以你的接口:

public interface IFilters<T> 
{ 
    Dictionary<string, List<T>> FilterLists { get; set; } 
} 
+0

也許T在這裏使用是錯誤的。我只是用它作爲一個佔位符來表示動態的東西,我們不知道在運行時會有什麼。接口本身沒有提及。我只需要在'List <>'之間插入一些東西,這樣當我在代碼中的其他地方實現時,我就可以用一個未知的傳入對象的List來填充它。 – 2014-08-27 15:13:46

+0

你在這裏討論的兩種不同的東西: - 如果你想知道什麼是運行時類型,那麼使用列表,但我不知道你將如何訪問對象,除非使用反射(這不是正確的事情做)。 - 但是,如果你知道對象的類型和編譯時間(當你編寫代碼的時候),並且每個項目都有所不同,那麼使用泛型約束是正確的選擇 – 2014-08-27 15:16:20

+0

@RobertBurke我會檢查你的問題現在編輯,對不起,我以前沒有看到它 – 2014-08-27 15:18:23