使子对象具有自己的类型静态容器

时间:2017-07-06 10:37:56

标签: c# oop generics

每个类对象是否都有自己的静态数据存储?

我的意思是,只是为了执行以下行动:

class Program
{
    static void Main(string[] args)
    {
        var car1 = new Car();
        car1.Save(); ////saves in its own storage
        var own1 = new Owner();
        own1.Save(); //saves in its own storage as well           
    }
}

在我试过的代码中,我收到了这样的错误

  

“System.InvalidCastException`

在这个地方 var repo = (Repository<IEntity>) CurrentRepository;

什么是错的,我怎么能做到?

整个代码在这里:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            //var car1 = new Car();
            //car1.Save(); ////saves in its own storage
            //var own1 = new Owner();
            //own1.Save(); //saves in its own storage as well    var car1 = new Car();

        }
    }

    public interface IEntity
    {
        long Id { get; }
    }

    public class Owner : Entity
    {

        public string FirstName { get; set; }

        public string LastName { get; set; }

        public Car Car { get; set; }

        public Owner(string firstName, string lastName, Car car) : base(new Owner())
        {
            FirstName = firstName;
            LastName = lastName;
            Car = car;
        }

        public Owner() : base()
        {
        }

    }

    public class Car : Entity
    {
        public string Name { get; set; }
        public int Year { get; set; }

        public Car() : base()
        {

        }

        public Car(string name, int year)
        {
            Name = name;
            Year = year;
        }
    }

    public abstract class Entity : IEntity
    {
        public long Id { get; }

        public static object CurrentRepository { get; set; }

        public Entity(Entity ent)
        {
            Type entityType = ent.GetType();
            var instance = Activator.CreateInstance(typeof(Repository<>).MakeGenericType(entityType));

            CurrentRepository = instance;

        }

        public Entity()
        {
        }

        public void Save()
        {
            var repo = (Repository<IEntity>)CurrentRepository;
            repo.Save(this);
        }

        public void Delete()
        {
            var repo = (Repository<IEntity>)CurrentRepository;
            repo.Delete(this);
        }
    }

    public interface IRepository<T> where T : IEntity
    {
        void Save(T entity);
        void Delete(T entity);
        T Find(long id);
    }

    public class Repository<T> : IRepository<T> where T : class, IEntity
    {
        protected BaseStorage<T> CustomDataStorage;

        public Repository()
        {
            CustomDataStorage = new BaseStorage<T>();
        }

        public void Save(T entity)
        {
            CustomDataStorage.Add(entity);
        }

        public void Delete(T entity)
        {
            CustomDataStorage.Remove(entity);
        }

        public T Find(long id)
        {
            throw new NotImplementedException();
        }
    }
    public class BaseStorage<T> : IStorage<T>
    {
        List<T> data = new List<T>();

        public void Add(T entity)
        {
            data.Add(entity);
        }

        public void Remove(T entity)
        {
            throw new NotImplementedException();
        }
    }

    public interface IStorage<T>
    {
        void Add(T entity);
        void Remove(T entity);
    }

}

2 个答案:

答案 0 :(得分:4)

  

在我试过的代码中,我收到了这样的错误

     
    

&#39; System.InvalidCastException`

  
     

在这个地方var repo =(Repository)CurrentRepository;

     

什么是错的,我怎么能做到?

这是因为您无法直接CurrentRepository类型(Repository<Car>Repository<Owner>)投射到{ {1}}。

有关详细信息,请参阅here ...

要想达到你想要的效果,你可以这样试试:

  1. Repository<IEntity>类设为通用(Entity)并将通用类型约束为Entity<T>
  2. 使IEntity成为CurrentRepository
  3. 的类型
  4. Repository<Entity<T>>的静态初始化从实例构造函数移动到静态构造函数。
  5. 使CurrentRepository的{​​{1}}和Owner对象子类与Car引用其自己的类型,使其成为自引用泛型
  6. <强>代码

    Entity<T>

答案 1 :(得分:1)

要考虑的一个选择是更改Entity,如下所示。

ConcurrentDictionary是为了确保每种类型都有一个存储库。

public abstract class Entity : IEntity
{
    public long Id { get; }

    public static ConcurrentDictionary<Type, dynamic> CurrentRepository = new ConcurrentDictionary<Type, dynamic>();

    public Entity(Entity ent)
    {
        GetRepository(ent);
    }

    private static dynamic GetRepository(Entity ent)
    {
        Type entityType = ent.GetType();

        return CurrentRepository.GetOrAdd(entityType, type =>
        {
            var instance = Activator.CreateInstance(typeof(Repository<>).MakeGenericType(entityType));
            return instance;
        });
    }

    public Entity()
    {
    }

    public void Save()
    {
        var repo = GetRepository(this);
        repo.Save((dynamic)this);
    }

    public void Delete()
    {
        var repo = GetRepository(this);
        repo.Delete((dynamic)this);
    }
}
相关问题