2012-05-16 106 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