如何使用也具有泛型返回的方法正确处理由泛型类组成的列表

时间:2015-05-31 10:39:50

标签: c# json generics interface abstract-class

我相信这个问题很简单,但由于我已经在这个问题上暂时搁浅了一段时间,我可能无法看到整体情况。

我想加载多个文件(在本例中为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#,并希望尽可能使用最好的编程实践。我希望拥有一个强大的代码,没有重复,并且类之间的依赖性最小。我也希望得到一个解释而不仅仅是一个有效的代码。谢谢!

1 个答案:

答案 0 :(得分:1)

  

我对接口有一些问题(它抱怨它不能   将JSONLoader表达式转换为type   ILoader)

这是因为List<T>不是协变的。如果您希望这样做,而不是公开List<T>,您可以在IEnumerable<T>中公开T协变,并使Loader<T>与{{1}协变}}:

Loader<out T>