简体   繁体   中英

using Generic interface type as basis for interface parameter type

I have the following:

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);
}

What I'd like is to be able to replace object itemId with the type of ItemId based on what implementation I'm using. I can do it using IItemRepository where U is the ItemId type, but I'd like to tie the itemId type directly to the ItemId Property Type. Also, I'm not necessarily tied to using IItemRepository as an interface. I could make it an abstract class, but I didn't see an easy way to do it that way either.

so, the end result is that I could do:

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

and that would satisfy the Interface. Is there a way to do something like :

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

Update: I cannot simply do IItemRepository , as I'll have multiple implementations of Item. each implementation will also have a repository (possibly multiple). so, the final WebService will have something like:

IEnumerable<IItemRepository<Item>> Repositories;

This list of repositories will be used to generate all different types of Items. I need to be able to distinguish between a Foo : Item and a Bar : Item ... I may just have to pass along the ItemIdType to the Repository, but it just feels clunky. Seems like I'm repeating myself and there should be some way to refactor this so I dont have to.

Another Update... So... Here's what I've started to come up with:

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}
}

The issue is that I need the StringItemRepository.GetItem to spit out StringItems, not Item objects. and my current implementation doesn't work cause StringItemRepository isn't implementing GetItem cause it's not returning Item ... You'd think that since StringItem is a Item it'd work, but no such luck.

I think I'm going to have to use 2 generic types.. (both the StringType and String) when I create the Repository unless someone else has another solution..

Okay... So, this worked:

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(); 
  }
}

I was hung up on having GetItem having a stringItem as a return type, but I can return a StringItem since it of type Item ... This will work out perfectly... thanks for all that helped out..

It sounds like you should make Item generic to start with - then you don't need StringItem at all, with its property hiding:

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

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

Why not implementing this like;

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();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM