为了账号安全,请及时绑定邮箱和手机立即绑定

通用集合重载器

通用集合重载器

C#
MMTTMM 2021-10-24 16:44:07
是否有可能改变特定类型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 方法。
查看完整描述

2 回答

?
莫回无

TA贡献1865条经验 获得超7个赞

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


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


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

}


查看完整回答
反对 回复 2021-10-24
?
摇曳的蔷薇

TA贡献1793条经验 获得超6个赞

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


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))

   {  

   }

}

然后我什至不明白为什么你首先需要第二个参数:当你可以让你的 reload 方法抽象时


protected abstract void Reload();

然后让你的班级实现它。


public class TestA: Test<TestItem>

{

    protected void Reload() => new ConcurentBag<TestItem>(LoadData())

}


查看完整回答
反对 回复 2021-10-24
  • 2 回答
  • 0 关注
  • 190 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信