我看到一个帖子,其中 Jon Skeet 发布了以下内容:
You can't use any parameterised constructor. You can use a parameterless constructor if you have a "where T : new()" constraint.
我有以下方法:
public T ReturnReader<T>(String filePath) where T : TextReader, new()
{
return new T(filePath);
}
这违反了他上面提到的内容。我需要上述方法才能返回 StreamReader(生产代码)和 StringReader(单元测试目的)。据我所知,streamReader 不包含无参数构造函数,因此我无法创建无参数实例,然后在调用方法中将文件路径分配给它。
有人看到这个问题的解决方案吗?
感谢您的宝贵时间!
编辑:原始方法,A 和 B
/// <summary>
/// Ensures number of columns stated == number of columns in file.
/// </summary>
/// <param name="errorMessageList">A running list of all errors encountered.</param>
public static void ValidateNumberOfColumns(string filePath, int userSpecifiedColumnCount, List<String> errorMessageList)
{
int numberOfColumnsInFile = GetNumberOfColumnsInFile(filePath, errorMessageList);
if (userSpecifiedColumnCount != numberOfColumnsInFile) errorMessageList.Add("Number of columns specified does not match number present in file.");
}
public static int GetNumberOfColumnsInFile(string filePath, List<String> errorMessageList)
{
int numberOfColumns = 0;
string lineElements = null;
try
{
using (StreamReader columnReader = new StreamReader(filePath))
{
lineElements = columnReader.ReadLine();
string[] columns = lineElements.Split(',');
numberOfColumns = columns.Length;
}
return numberOfColumns;
}
catch (Exception ex)
{
errorMessageList.Add(ex.Message);
return -1;
}
}
最佳答案
如果您必须求助于反射以使代码对单元测试可行,这有点奇怪 - 只是一个指示您可能想要重新考虑设计,但肯定需要考虑的事情.
我很想将其抽象为一个单独的接口(interface) - IPathReader
或类似的东西:
public interface IPathReader
{
TextReader CreateReader(string path);
}
然后将其注入(inject)到您正在测试的类中 - 使用 StringReader
实现在测试中,以及使用 StreamReader
的实现在生产中。 (我怀疑您并不真的需要它来返回不同的类型。)
请注意,这实际上只是一个 Func<string, TextReader>
- 因此您可以根据需要使用它而不是界面。
关于c# - 通用方法,是否可以返回 StreamReader 实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11708939/