我相信这个问题很简单,但由于我已经在这个问题上暂时搁浅了一段时间,我可能无法看到整体情况。
我想加载多个文件(在本例中为JSON),因此我创建了一个DataLoader
类来处理这个问题。在本课程中,我创建了一个ILoaders
列表,该类将迭代并加载,以便将来如果我使用的不是JSON,那么抽象就已经实现了。
public class DataLoader{
private List<IDataLoaded> allDataLoaded = new List<IDataLoaded>();
private List<ILoader> loaderLists = new List<ILoader> (){
new JSONLoader<RootSpacecrafts>(),
new JSONLoader<RootWeapons>()
};
public void LoadData(){
foreach(ILoader loader in loaderLists){
loader.Read ();
IDataLoaded dataLoaded = loader.Load ();
allDataLoaded.Add(dataLoaded);
}
}
}
当我创建JSONLoader
类并使其实现ILoader
接口时,我注意到我必须将ILoader
转换为通用接口:我将始终需要提供根T
将数据放入的类JSONLoader
,并且还需要它灵活并返回包含所加载数据的List<T>
。
所以现在我的JSONLoader
类读作:
public class JSONLoader<T> : ILoader<T> where T : IDataLoaded, new(){
private string fileContents;
private T output = new T();
private List<T> outputlist;
public void Read(){
fileContents = File.ReadAllText(Paths.Get(output.Descriptor));
outputlist = JsonConvert.DeserializeObject<List<T>>(fileContents);
}
public List<T> Load(){
return outputlist;
}
}
和ILoader:
public interface ILoader<T>{
void Read();
List<T> Load();
}
现在,当我回到DataLoader
课程时,正如您所看到的,我失去了调用ILoader
的灵活性,因为我需要告诉我们使用的泛型类是什么。 / p>
我尝试将其封装在另一个界面中,但loader.Load()
中的DataLoader
调用已被破坏,因为它返回List<T>
。
现在我觉得要在一边修好,我会打破另一边。我一直在努力思考抽象类和接口的良好组合,以便相应地隔离所有内容,但是我在查看它如何适合的时候遇到了很大的麻烦(我对C#和我来说相当陌生)还没有精神敏捷性,看看我应该做些什么并封装起来。
我将此作为练习学习C#,并希望尽可能使用最好的编程实践。我希望拥有一个强大的代码,没有重复,并且类之间的依赖性最小。我也希望得到一个解释而不仅仅是一个有效的代码。谢谢!
答案 0 :(得分:1)
我对接口有一些问题(它抱怨它不能 将JSONLoader表达式转换为type ILoader)
这是因为List<T>
不是协变的。如果您希望这样做,而不是公开List<T>
,您可以在IEnumerable<T>
中公开T
协变,并使Loader<T>
与{{1}协变}}:
Loader<out T>