尝试实现接口时的泛型

时间:2018-03-08 05:34:49

标签: c# .net generics

问题:我有很多要解析的文件类型。每个解析一个文件并返回一个对象的结果(List<>)。我想只有一个IFileParser接口,并在调用Parse时指定解析器类型和返回集

我有这样的界面

public interface IFileParser
{
    TResponse Parse<TFileParserType,TResponse>(string file);
}

被注入这样的服务

private readonly IFileParser _fileParser;
 public CarService(IFileParser fileParser)

        {
            _fileParser = fileParser;

        }

正在使用

var cardatas = _fileParser.Parse<CarFileParser, List<CarData>>("car.txt");
  var bikedatas = _fileParser.Parse<BikeFileParser, List<BikeData>>("bike.txt");

实施 - 这部分不起作用......为什么? 返回的错误是

  

无法隐式转换类型'System.Collections.Generic.List&lt; CarData&gt;'到'System.Collections.Generic.List&lt; TResponse&gt;'

 public class CarFileParser : IFileParser
    {
        public List<CarData> Parse(string filePath)
        {
            return new List<CarData>() //does not work...why??
        }


        public TResponse Parse<TType, TResponse>(string file)
        {
            throw new NotImplementedException(); 
            //this is what it should be 
            //but how do I return a List<CarData> 
        }
    }

4 个答案:

答案 0 :(得分:0)

不要求这是答案。这有用吗:

public interface IFileParser<TResponse>
    {
        TResponse Parse(string file);
    }

    public class CarFileParser : IFileParser<List<CarData>>
    {
        public List<CarData> Parse(string file)
        {
            throw new NotImplementedException();
        }
    }

答案 1 :(得分:0)

首先,返回类型应与返回值匹配:

    public List<CarData> Parse(string filePath)
    {
        return new List<CarData>() //Will work..
    }

在进行类型转换时,列表无法转换为类。如果你想要这个,请在​​课堂上创建一个属性。

    var cardatas = _fileParser.Parse<CarFileParserList, List<CarData>>("car.txt");

    class CarFileParser
    {
     public List<CarFile> CarFileParserList{get;set;}
    }

    public class CarFile
    {
     //create property here
    }

然后你可以使用这段代码:

     var cardatas = _fileParser.Parse<List<CarFile>, List<CarData>>("car.txt");
     var carFileParser= new CarFileParser();
     carFileParser.CarFileParserList=cardatas;

答案 2 :(得分:0)

如果它总是返回一个列表,可以尝试

 List<TResponse> Parse<TFileParserType, TResponse>(string file);

然后

 List<CarData> cardatas = _fileParser.Parse<CarFileParser, CarData>("car.txt");

(或可能是ICollection / IEnumerable

答案 3 :(得分:0)

一般来说,我更喜欢像这样实现类型/接口。不确定这是否适用于您的注射。

// Put the type of data on the interface / type
public interface IFileParser<TData>
{
    IEnumerable<TData> Parse(string file);
}

// Implement the interface
public class CarParser : IFileParser<CarData>
{
    ...
}

// The method where to inject the implementation:
public IEnumerable<TData> Parse<TData>(IFileParser<TData> parser, string file)
{
    return parser.Parse(file);
}

// The implementations would have to be injected here:
private readonly IFileParser<CarData> _carFileParser;
private readonly IFileParser<BikeData> _bikeFileParser;

var carData = Parse(_carFileParser, file);
var bikeData = Parse(_bikeFileParser, file);