我有兩種不同型別的專案:圖片和視頻。為了管理它們,我創建了一個介面和兩個實作它的類
public interface Item{
}
public class ItemPicture: Item{
}
public class ItemVideo: Item {
}
現在我有一些類來管理那些從管理器介面繼承的專案
public interface ItemManager<T>{
IList<T> FGetByGroup(string idgroup);
}
public class ItemManagerPictures : IItemManager<ItemPicture>{
public IList<ItemFoto> FGetByGroup(string idgroup){
...
}
}
public class ItemManagerVideos: IItemManager<ItemVideo>{
public IList<ItemVideo> FGetByGroup(string idgroup){
...
}
}
為了有一個創建適當物件的工廠方法,我創建了這個類
public class ItemManagerCreator
{
public static IItemManager<Item> MakeItemManager(string type)
{
IItemManager<Item> objMgr = null;
switch (type)
{
case "Picture":
objMgr = (IItemManager<Item>)new ItemManagerPictures();
break;
case "Video":
objMgr = (IItemManager<Item>)new ItemManagerVideos();
break;
default:
break;
}
return objMgr ;
}
}
從控制器我想這樣做
var type="Picture";
IItemManager<Item> itemMgr = ItemManagerCreator.MakeItemManager(type);
var itemList = itemMgr.FGetByGroup(string idgroup);
但我得到這個鑄造錯誤
無法從型別“...ItemManagerPictures”轉換為型別“...IItemManager`1[...Item]”。
這讓我覺得我做錯了什么,但是經過 1000 圈之后,我認為問題出在工廠方法和泛型上,它們設計得不好。
我是設計模式的新手,也許我沒有應用正確的模式。
提前致謝
uj5u.com熱心網友回復:
它不能按原樣作業,因為ItemManagerPictures并且ItemManagerVideos確實不能轉換為IItemManager<Item>,請檢查協方差和逆變以了解原因。
在這種情況下,因為您實際上不需要使用IListof 的回傳型別FGetByGroup(如注釋中所示),您可以通過使用一些在泛型型別T(例如IEnumerable<T>or IReadOnlyList<T>)中協變的介面來使其作業,然后將您的型別宣告T為也是協變的:
public interface IItemManager<out T>{
IReadOnlyList<T> FGetByGroup(string idgroup);
}
public class ItemManagerPictures : IItemManager<ItemPicture>{
public IReadOnlyList<ItemPicture> FGetByGroup(string idgroup) {
return null;
}
}
現在,ItemManagerPictures是可分配的,IItemManager<Item>因此您的代碼將毫無例外地作業。
uj5u.com熱心網友回復:
從您的代碼中,您似乎事先知道您想要什么型別的 ItemManager,因此您可以執行以下操作:
public class ItemManagerCreator
{
public static IItemManager<T> MakeItemManager<T>() where T : Item
{
if (typeof(T) == typeof(ItemPicture))
{
return (IItemManager<T>)new ItemManagerPictures();
}
if (typeof(T) == typeof(ItemVideo))
{
return (IItemManager<T>)new ItemManagerVideos();
}
throw new InvalidOperationException();
}
}
并使用:
string groupId = string.Empty;
dynamic itemManager = null;
我想要一個IItemManager圖片
itemManager = ItemManagerCreator.MakeItemManager<ItemPicture>();
IList<ItemPicture> pictures = itemManager.FGetByGroup(groupId);
然后我想要一個IItemManager視頻
itemManager = ItemManagerCreator.MakeItemManager<ItemVideo>();
IList<ItemVideo> videos = itemManager.FGetByGroup(groupId);
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/341024.html
