猿问

通用集合重载器

是否有可能改变特定类型Ex: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>

更新


我想将重新加载机制分离到父母的类中。我可以有两种重载机制:简单和复杂(在重载方法中调用几个方法)。孩子们的班级可以访问存储库和工厂。有几个insert、create方法在子类中继承类的数据源上使用linqu。复杂的机制包含额外的字段和方法,所以我不想重复代码。在这种情况下怎么做会更好?我可以使用也实现 IEnumerable 的字典吗?


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


MMTTMM
浏览 191回答 2
2回答

莫回无

这是可能的,但有点脆弱的设计,因为它依赖于这样一个事实,ConcurrentBag<T>并且List<T>可以将 IEnumerable 作为构造函数参数并填充自身。如果您需要支持构造函数参数不一致的类型,我建议使用 johnny 的答案。无论如何,你只需要一个这样的类型约束:public abstract class Test<TItem,TContainer> : IRepositoryLoader<TItem>&nbsp;&nbsp; &nbsp; where TContainer : class, IEnumerable<TItem>而 ReloadData() 看起来像这样:void IRepositoryReloader.ReloadData(){&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; this.Source = (TContainer)Activator.CreateInstance(typeof(TContainer), new [] { LoadData() } );}

摇曳的蔷薇

非常不清楚您想要从问题中得到什么,但从它的外观来看,您需要多种可枚举类型,具体取决于您使用的类。public abstract class Test<T, TEnumerable> : IRepositoryLoader<T>&nbsp; &nbsp; Where TEnumerable : IEnumerable<T>{&nbsp; &nbsp; Func<IEnumerable<T>, TEnumerable> _enumerableResolver;&nbsp; &nbsp; public Test(Func<IEnumerable<T>, TEnumerable> enumerableResolver)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;this._enumerableResolver = enumerableResolver&nbsp; &nbsp; }&nbsp; &nbsp; protected TEnumerable Source;&nbsp; &nbsp; public abstract IEnumerable<T> LoadData();&nbsp; &nbsp; private void IRepositoryRelouder.Reload() =>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; Source = this._enumerableResolver(LoadData());}然后你可以像这样调用实例化:public class TestA: Test<TestItem, ConcurentBag<TestItem>>{&nbsp; &nbsp;public TestA() : base(x => new ConcurentBag<TestItem>(x))&nbsp; &nbsp;{&nbsp;&nbsp;&nbsp; &nbsp;}}然后我什至不明白为什么你首先需要第二个参数:当你可以让你的 reload 方法抽象时protected abstract void Reload();然后让你的班级实现它。public class TestA: Test<TestItem>{&nbsp; &nbsp; protected void Reload() => new ConcurentBag<TestItem>(LoadData())}
随时随地看视频慕课网APP
我要回答