问题:我有很多要解析的文件类型。每个解析一个文件并返回一个对象的结果(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>
}
}
答案 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);