c# - 通用方法,是否可以返回 StreamReader 实例?

标签 c# unit-testing c#-4.0 generics

我看到一个帖子,其中 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/

相关文章:

c# - 在 Datagridview 中显示数据库搜索结果

c# - 在 NodaTime 中获取夏令时开始和结束时间

android - Schedulers.immediate() 不适用于命令行 gradle 测试

linq - 在使用 LINQ to Object 的单元测试中复制 LINQ to Entities 行为

design-patterns - 有人可以批评我的工厂模式吗?

c# - 我是 .NET 的新手 - 我应该关注什么,应该忽略什么?

c# - 配置多个数据库 Entity Framework 6

Android - Assertj Android - 运行错误

multithreading - 如何确保线程之间唯一的本地状态以进行电子邮件队列处理

jquery - 415 不支持的媒体类型从 $.ajax 调用 WCF 服务