通用集合重新加载器

时间:2018-07-23 19:20:49

标签: c#

是否可以将特定类型从ConcurentBag<T>更改为S类型。 我想制作一个通用类,用于加载数据并重新加载源集合(list<T>ConcurrentBag<T>,字典)

这是我的代码:

public interface IRepositoryRelouder
{
    private void ReloadData();
}
public interface IRepositoryLoader<out T> : IRepositoryRelouder
{
    IEnumerable<T> LoadData();
}
public abstract class Test<T> : IRepositoryLoader<T>
{
    protected ConcurrentBag<T> Source;
    public abstract IEnumerable<T> LoadData();

    private void void IRepositoryRelouder.Reload() => 
        Source = new ConcurrentBag<T>(LoadData());
}

我想在父类中加载和重新加载数据,并创建可以访问Source属性的子类。将ConcurentBag替换为下一个通用参数是否可以通过?

我想知道是否可能出现这样的情况:

 public abstract class Test<T,S> : IRepositoryLoader<T>
    {
        protected S <T> Source;
        public abstract IEnumerable<T> LoadData();

        private void void IRepositoryRelouder.Reload() => 
            Source = new S <T>(LoadData());
    }

Where S is ConcurrentBag<T> or List<T>

更新

我想将重载机制分为父母的班级。 我可以有两种重载机制:简单和复杂(在重载方法内部调用了几种方法)。孩子们的班级可以访问存储库和工厂。 在子类的继承类中,有几种在数据源上使用linqu的insert,create方法。复杂的机制包含其他字段和方法,因此我不想重复代码。 在这种情况下最好做些什么? 我可以使用也实现IEnumerable的字典吗?

IRepositoryRelouder接口仅适用于在配置类中实现此接口的ech类的调用Reload方法。

2 个答案:

答案 0 :(得分:1)

不清楚您要从问题中得到什么,但是从它的外观上,您需要多种可枚举类型,具体取决于您使用的是什么类。

public abstract class Test<T, TEnumerable> : IRepositoryLoader<T>
    Where TEnumerable : IEnumerable<T>
{
    Func<IEnumerable<T>, TEnumerable> _enumerableResolver;
    public Test(Func<IEnumerable<T>, TEnumerable> enumerableResolver)
    {
         this._enumerableResolver = enumerableResolver
    }

    protected TEnumerable Source;
    public abstract IEnumerable<T> LoadData();

    private void IRepositoryRelouder.Reload() => 
        Source = this._enumerableResolver(LoadData());
}

然后您可以这样调用实例化:

public class TestA: Test<TestItem, ConcurentBag<TestItem>>
{
   public TestA() : base(x => new ConcurentBag<TestItem>(x))
   {  
   }
}

然后我什至看不到为什么首先需要第二个参数: 什么时候可以让重载方法变得抽象

protected abstract void Reload();

然后让您的类实现它。

public class TestA: Test<TestItem>
{
    protected void Reload() => new ConcurentBag<TestItem>(LoadData())
}

答案 1 :(得分:1)

这是可能的,但是有点脆弱的设计,因为它依赖于ConcurrentBag<T>List<T>都可以将IEnumerable作为构造函数参数并填充自身的事实。如果您需要像这样的构造函数参数不一致的类型,我建议约翰尼的答案。

无论如何,您只需要这样的类型约束:

public abstract class Test<TItem,TContainer> : IRepositoryLoader<TItem> 
    where TContainer : class, IEnumerable<TItem>

ReloadData()看起来像这样:

void IRepositoryReloader.ReloadData()
{       
    this.Source = (TContainer)Activator.CreateInstance(typeof(TContainer), new [] { LoadData() } );
}

看到我的full working example on DotNetFiddle