Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否可以为存储库模式创建强类型类?_C# - Fatal编程技术网

C# 是否可以为存储库模式创建强类型类?

C# 是否可以为存储库模式创建强类型类?,c#,C#,我正在尝试实现一个存储库模式,但是我不明白当实体具有不同类型的id时,它是如何可能的。目前,我不得不回退到使用object,而我确实希望使用存储库所持有的实体的特定类型的id interface IEntity { object GetId(); } class Foo : IEntity { private string id; public Foo(string id) { this.id = id; } public o

我正在尝试实现一个存储库模式,但是我不明白当实体具有不同类型的id时,它是如何可能的。目前,我不得不回退到使用object,而我确实希望使用存储库所持有的实体的特定类型的id

interface IEntity
{
    object GetId();
}

class Foo : IEntity
{
    private string id;

    public Foo(string id)
    {
        this.id = id;
    }

    public object GetId()
    {
        return id;
    }
}

class Bar : IEntity
{
    private int id;

    public Bar(int id)
    {
        this.id = id;
    }

    public object GetId()
    {
        return id;
    }
}

class Repository<T> where T : IEntity
{
    private Dictionary<object, T> entities = new Dictionary<object, T>();

    public IEnumerable<T> List => entities.Values.AsEnumerable();

    public void Add(T entity)
    {
        entities.Add(entity.GetId(), entity);
    }

    public T Get(object id)
    {
        return entities[id];
    }
}

class Program
{
    static void Main(string[] args)
    {
        var foo = new Foo("0");

        var bar = new Bar(0);

        var fooRepo = new Repository<Foo>();
        fooRepo.Add(foo);
        fooRepo.Get(foo.GetId());

        var barRepo = new Repository<Bar>();
        barRepo.Add(bar);
        barRepo.Get(bar.GetId());
    }
}
我也试过这样的方法:

class Repository<Id, Value> where Value : IEntity
{
    private Dictionary<Id, Value> entities = new Dictionary<Id, Value>();

    public IEnumerable<Value> List => entities.Values.AsEnumerable();

    public void Add(Value entity) // But got stuck here, I don't want to pass in Id as separate parameter, I want it auto magically from the interface.
    {
        entities.Add(entity.GetId(), entity);
    }

    public Value Get(Id id)
    {
        return entities[id];
    }
}

您可以将键的泛型类型添加到IEntity。例如:

界面粗糙度 { TId GetId; } Foo类:智能 { 私有字符串id; 公共食物字符串id { this.id=id; } 公共字符串GetId { 返回id; } } 类存储库,其中tenty:ienty { 私有字典实体=新字典; 公共无效附加实体 { entities.Addentity.GetId,entity; } 公共TEntity GetTId id { 返回实体[id]; } }
乔尔的解决方案可以扩展到允许差异。泛型集合实现IEnumerable和IEnumerable的方式相同

实体

interface IEntity
{
    object GetId();
}

interface IEntity<TId> : IEntity
{
    new TId GetId();
}

abstract class EntityBase<TId> : IEntity<TId>
{
    protected TId id;

    protected EntityBase(TId id)
    {
        this.id = id;
    }

    public TId GetId() => id;

    object IEntity.GetId() => GetId();
}
首先,它不是一个存储库模式,它是一个通用的存储库,一些开发人员认为它不仅仅是有用的东西,主要是因为我们对抽象有抽象作用。您可以将IEntity接口设置为通用接口,然后执行以下操作:class Repository,其中Value:IEntity
abstract class Repository
{
    protected Dictionary<object, IEntity> entities;

    protected Repository()
    {
        entities = new Dictionary<object, IEntity>();
    }

    public virtual void Add(IEntity entity) 
    {
        if (entity == null) throw new ArgumentNullException(nameof(entity));
        entities.Add(entity.GetId(), entity);
    }

    public virtual IEntity Get(object id)
    {
        if (id == null) throw new ArgumentNullException(nameof(id));
        return entities[id];
    }
}

abstract class Repository<TId, TEntity> : Repository 
    where TEntity : class, IEntity<TId>
{
    protected Repository() : base() { }

    public override void Add(IEntity entity)
    {
        Add((TEntity)entity);
    }

    public override IEntity Get(object id)
    {
        return Get((TId)id);
    }

    public void Add(TEntity entity)
    {
        if (entity == null) throw new ArgumentNullException(nameof(entity));
        entities.Add(entity.GetId(), entity);
    }

    public TEntity Get(TId id)
    {
        if (id == null) throw new ArgumentNullException(nameof(id));
        return (TEntity)entities[id];
    }
}
class Foo : EntityBase<string>
{
    public Foo(string id) : base(id) { }
}

class Bar : EntityBase<int>
{
    public Bar(int id) : base(id) { }
}

class FooRepository : Repository<string, Foo>
{
    public FooRepository() { }
}

class BarRepository : Repository<int, Bar>
{
    public BarRepository() { }
}
[TestMethod]
public void IEntitySupport()
{
    // use IEntity and object
    IEntity bar = new Bar(1);
    Repository barRepository = new BarRepository();
    barRepository.Add(bar);
    var bar2 = barRepository.Get((object)1);
    Assert.AreSame(bar, bar2);
}

[TestMethod]
public void TEntitySupport()
{
    // use TEntity and TId
    var foo = new Foo("a");
    var fooRepository = new FooRepository();
    fooRepository.Add(foo);
    var foo2 = fooRepository.Get("a");
    Assert.AreSame(foo, foo2);
}