简体   繁体   English

使用通用接口类型作为接口参数类型的基础

[英]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. 我想要的是能够根据我正在使用的实现将ItemId替换为ItemId的类型。 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. 我可以使用IItemRepository来实现它,其中U是ItemId类型,但我想将itemId类型直接绑定到ItemId属性类型。 Also, I'm not necessarily tied to using IItemRepository as an interface. 另外,我不一定要将IItemRepository用作接口。 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. 更新:我不能简单地做IItemRepository,因为我将有多个Item的实现。 each implementation will also have a repository (possibly multiple). 每个实现也将有一个存储库(可能是多个)。 so, the final WebService will have something like: 所以,最终的WebService将具有以下内容:

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. 我需要能够区分Foo:Item和Bar:Item ...我可能只需要将ItemIdType传递给Repository,但它只是感觉笨重。 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. 问题是我需要StringItemRepository.GetItem来吐出StringItems,而不是Item对象。 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. 我当前的实现不起作用因为StringItemRepository没有实现GetItem因为它没有返回Item ...你会认为因为StringItem是一个它可以工作的项目,但没有这样的运气。

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.. 我想在创建存储库时我将不得不使用2种泛型类型(包括StringType和String),除非其他人有其他解决方案。

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.. 我被挂起来让GetItem有一个stringItem作为返回类型,但我可以返回一个StringItem,因为它类型为Item ...这将完美地运行...感谢所有帮助...

It sounds like you should make Item generic to start with - then you don't need StringItem at all, with its property hiding: 听起来你应该让Item开头 - 然后你根本不需要StringItem ,它的属性隐藏:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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