2012-05-16 177 views
1

我有以下幾點:使用通用接口類型爲接口的參數類型基礎

class Item { 
    public object ItemId {get;set;} 
} 

class StringItem : Item { 
    public new string ItemId {get;set;} 
} 

interface IItemRepository<out T> : where T : Item { 
    T GetItem(object itemId); 
} 

我想是基於什麼我實現能夠與項目Id的類型來代替對象的itemId使用。我可以使用IItemRepository來完成,其中U是ItemId類型,但我想將itemId類型直接綁定到ItemId屬性類型。另外,我並不一定要使用IItemRepository作爲接口。我可以把它變成一個抽象類,但是我沒有看到用這種方式做到這一點的簡單方法。

所以,最終的結果是,我可以這樣做:

StringItemRepository : IItemRepository<StringItem> { 
    StringItem GetItem(string itemId) { ... } 
} 

這將滿足該接口。有沒有辦法做這樣的事情:

T GetItem(typeof(T.ItemId.GetType()) itemId); 

更新: 我不能簡單地做IItemRepository,因爲我有項目的多個實現。每個實現也將有一個存儲庫(可能是多個)。因此,最終的WebService將具有類似的內容:

IEnumerable<IItemRepository<Item>> Repositories; 

此存儲庫列表將用於生成所有不同類型的項目。我需要能夠區分Foo:Item和Bar:Item ...我可能只需要將ItemIdType傳遞給Repository,但它只是感覺笨重。似乎我重複自己,應該有一些方法來重構這個,所以我不必。

另一個更新...所以...這裏是我開始拿出:

class Item<T> { 
    public T id {get;set;} 
} 

class StringItem : Item<string> { 
    public string id {get;set;} 
} 

interface IItemRepo<T> { 
    Item<T> GetItem(T id); 
} 

class StringItemRepository : IItemRepo<string> { 
    public StringItem GetItem(string id) { return null} 
} 

的問題是,我需要的StringItemRepository.GetItem吐出StringItems,而不是項目的對象。和我當前的實現不起作用因爲StringItemRepository沒有實現GetItem因爲它沒有返回項目...你會認爲,因爲StringItem是一個項目它會工作,但沒有這樣的運氣。

我想我將不得不當我創建除非別人有另一種解決方案存儲庫使用2種泛型類型。(該StringType和字符串兩者)..

好了...所以,這工作:

class Item<T> { 
    public T id {get;set;} 
} 

class StringItem : Item<string> { 
    public string id {get;set;} 
} 

interface IItemRepo<T> { 
    Item<T> GetItem(T itemId); 
} 

class StringItemRepository : IItemRepo<string> { 
    public Item<string> GetItem(string itemId) { 
    return new StringItem(); 
    } 
} 

我掛了具有帶有StringItem的作爲返回類型的GetItem,但因爲它我可以返回一個類型項目的StringItem的......這將制定出完美的...感謝所有幫助..

+2

爲什麼不做一個項目泛型類型繼承自Item並重寫ItemId來處理類型轉型? –

+0

@ChrisSinclair:正是我的建議 - 雖然除非你真的需要非泛型,我也會擺脫這個:) –

+0

@JonSkeet對於shizzle,只是覺得也許ItemId是無類型的,因爲像其他一些管理班級不知道/關心類型。EEEEEEEEEEEE首先回復Jon Skeet! –

回答

3

這聽起來像你應該讓Item通用的 - 開始,則你不需要StringItem可言,其財產隱藏:

class Item<T> { 
    public T ItemId { get; set; } 
} 

interface IItemRepository<T> { 
    Item<T> GetItem(T itemId); 
} 
+1

只需要屬性中的'T':'public T ItemId {get;組; }' – SwDevMan81

+1

是啊,杜。我想如果我要使用泛型,可能也會使用它們......(:有時候,這是容易讓事情變得黯然失色的事情。謝謝你。 – Rob

+0

@Rob我玩Portal的時候有同樣的問題,我經常忘記我有一個光圈科學手持門戶設備使我的生活變得更加困難 –

0

爲什麼不執行這一等;

public class Item<T> 
{ 
    public T ItemId { get; set; } 
} 

public class StringItem<T> : Item<T> 
{ 

} 

public interface IItemRepository<T> 
{ 
    Item<T> GetItem(T itemId); 
} 

public class StringItemRepository<T> : IItemRepository<T> 
{ 
    public Item<T> GetItem(T itemId) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+0

'StringItem'可能看起來像這樣:'public class StringItem:Item ' – SwDevMan81

+0

@ SwDevMan81你可能是對的,實際上如果一些自定義沒有實現,它也可以被刪除。但是如果班級有其他需要使用T的方法,它可能會被保留下來。很多maybes。 – daryal

+0

確實... stringItem確實是Item ,其中存在問題..(: – Rob