是否可以将特定类型从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方法。
答案 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() } );
}