[英]C# - Generic function to modify data structures specific to each type
我在使用泛型方面遇到了一些麻煩。
我想編寫一個給定類型的泛型函數,修改該類型的數據結構。
public static Dictionary<int, User> Users = new Dictionary<int, User>();
public static Dictionary<int, Item> Items = new Dictionary<int, Item>();
public static Dictionary<int, Store> Stores = new Dictionary<int, Store>();
public static void AddStuff<T>(T stuffToAdd)
{
(What dict goes here?).TryAdd(stuffToAdd.Id, stuffToAdd)
}
我想稱之為:
AddStuff<User>(some_user);
因此,根據調用的類型,我必須弄清楚如何找到與該類型相關的數據結構並添加/刪除它的內容。 對我來說有什么想法?
編輯:我有20個這樣的詞典。
我在使用泛型方面遇到了一些麻煩。
是的,你是。 注意那種感覺。 它告訴你,你在濫用泛型。
我想編寫一個給定類型的泛型函數,修改該類型的數據結構。
我最好的建議是:不要那樣想。 泛型應該是通用的 。 這就是為什么他們被稱為泛型 。 如果您基於泛型類型參數執行不同的操作,那么您的代碼不是通用的 。
我想稱之為:
AddStuff<User>(some_user);
別想了。
相反,編寫三個方法,並將它們稱為:
AddUserStuff(someUser);
AddItemStuff(someItem);
AddStoreStuff(someStore);
等等。 從邏輯上講,您有三種方法可以執行三種不同的操作,因此它們不是通用的 。 寫三種方法!
編輯:我有20個這樣的詞典。
寫出20種方法。 這並不難,而且比編寫一個有20個案例的“通用”方法更容易 ,因為它看起來很通用,但實際上並非如此。
看到你的用法AddStuff<User>(some_user)
,也可能是AddStuff(some_user)
,我沒有看到具有泛型的意義。 而不是使用無法編譯時驗證的東西(通用User
, Item
或Store
或其他東西)。 例如, AddStuff<string>("oops invalid usage")
會產生運行時問題。 您也可以為每種類型使用重載。 您可以擁有私人幫助函數,例如Paul的擴展示例。
使用John Wu關於使用IHasId
接口的想法,您可以創建一個這樣的私有助手:
private static void AddStuff<T>(Dictionary<int, T> dict, T stuffToAdd)
where TValue : IHasId
{
dict.TryAdd(stuffToAdd.Id, stuffToAdd)
}
您可以使用它並創建簡單的重載:
public static void AddStuff(User user) => AddStuff(Users, user);
public static void AddStuff(Item item) => AddStuff(Items, item);
public static void AddStuff(Store store) => AddStuff(Stores, store);
您可以使用if / else if或switch(僅限C#7)來完成此操作。
public static void AddStuff<T>(T stuffToAdd)
{
switch (stuffToAdd)
case User:
Users.TryAdd(stuffToAdd.Id, stuffToAdd);
// More cases
}
PS:在移動和公共汽車上。 因此,請進行必要的更正以使其編譯等。另外正如其他人指出的那樣,您實際上並不需要通用。 所以不要使用我在這里展示的內容!
為了能夠訪問Id屬性,您需要一個通用接口和一個類型約束。 在我的示例中,我包含一個IHasId
接口,因此所有域類型都具有該ID可用。
要選擇字典,您只需要將它們排列在更大的字典中。 在我的例子中,我稱之為dictionaries
。
//This interface allows you to specify a type constraint so AddStuff can use the Id property
public interface IHasId
{
int Id { get; }
}
public class User : IHasId { public int Id { get; set; } }
public class Item : IHasId { public int Id { get; set; } }
public class Store : IHasId { public int Id { get; set; } }
public class Program
{
public static Dictionary<int, User> Users = new Dictionary<int, User>();
public static Dictionary<int, Item> Items = new Dictionary<int, Item>();
public static Dictionary<int, Store> Stores = new Dictionary<int, Store>();
//This "outer" dictionary will allow AddStuff to look up the right dictionary based on the type.
public static Dictionary<Type,IDictionary> dictionaries = new Dictionary<Type,IDictionary>
{
{ typeof(User ), Users },
{ typeof(Item ), Items },
{ typeof(Store), Stores}
};
public static void AddStuff<TValue>(TValue stuffToAdd) where TValue : IHasId
{
IDictionary d = dictionaries[typeof(TValue)] as Dictionary<int, TValue>;
d.Add(stuffToAdd.Id, stuffToAdd);
}
public static void Main()
{
AddStuff( new User { Id = 1} );
AddStuff( new User { Id = 2} );
AddStuff( new Item { Id = 3} );
AddStuff( new Item { Id = 4} );
AddStuff( new Store { Id = 5} );
AddStuff( new Store { Id = 6} );
Console.WriteLine("Users: " + string.Join(",", Users.Select( u => u.Value.Id )));
Console.WriteLine("Items: " + string.Join(",", Items.Select( i => i.Value.Id )));
Console.WriteLine("Stores: " + string.Join(",", Stores.Select( s => s.Value.Id )));
}
}
輸出:
Users: 1,2
Items: 3,4
Stores: 5,6
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.