首页 > 解决方案 > 方法声明中的变量= null?这是什么意思以及如何调用此方法?

问题描述

今天在浏览一些代码时,偶然发现了以下方法声明

public List<Tuple<DataTable, string>> GetFileData(string directoryPath, string columnName = null)

我构建了类似的东西并尝试使用单个参数调用此方法,我认为既然我已经声明columnName = null我可以选择在这里发送一个参数。显然,情况并非如此。

我做了一个界面

public interface IExcelDataExtractor
{
    List<Tuple<DataTable, string>> GetFileData(string directoryPath, string columnName);
}

并实施

public class ExcelDataExtractor : IExcelDataExtractor
{
    /// <summary>
    /// Loops through each file in given directory and extracts the data
    /// </summary>
    /// <param name="directoryPath">the directory in which to look for the excel files</param>
    /// <param name="columnName">extractor will look for a sheet with the columName present to pull data from in case of multiple sheets, or a single sheet if null is passed</param>
    public List<Tuple<DataTable, string>> GetFileData(string directoryPath, string columnName = null)
    {
        //Initiate list of tuples
        List<Tuple<DataTable, string>> dataTableWithFileName = new List<Tuple<DataTable, string>>();

        //Loop through each file in directory with a filter on *.xls*, this should catch both .xls and .xlsx
        foreach (string file in Directory.EnumerateFiles(directoryPath, "*.xls*"))
        {
            DataSet ds;
            DataTable dt;

            ds = Read(file);
            dt = ExtractDataByColumn(ds, columnName);
            if (dt is null)
            {
                return null;
            }

            dataTableWithFileName.Add(Tuple.Create(dt, file));
        }

        return dataTableWithFileName;

    }

    /// <summary>
    /// Reads excel files and sends data to dataset with each sheet being a data table within the sheet
    /// </summary>
    /// <param name="file">file to open and add to the dataset</param>
    /// <returns>returns the dataset from the file</returns>
    private DataSet Read(string file)
    {
        using (var stream = File.Open(file, FileMode.Open, FileAccess.Read))
        {
            using (IExcelDataReader reader = ExcelReaderFactory.CreateReader(stream))
            {
                var conf = new ExcelDataSetConfiguration
                {
                    ConfigureDataTable = _ => new ExcelDataTableConfiguration
                    {
                        UseHeaderRow = true
                    }
                };

                return reader.AsDataSet(conf);
            }
        }
    }


    private DataTable ExtractDataByColumn(DataSet dataSet, string columnName = null)
    {
        if (!string.IsNullOrEmpty(columnName))
        {
            foreach (DataTable table in dataSet.Tables)
            {
                DataColumnCollection columns = table.Columns;
                if (columns.Contains(columnName))
                {
                    return table;
                }

            }
        }
        else
        {
            //If no columnName is given & more than 1 sheet is present, we want this to fail, else, return the single table
            foreach (DataTable table in dataSet.Tables)
            {
                if (dataSet.Tables.Count > 1)
                {
                    return null;
                }
                else
                {
                    return table;
                }
            }
        }

        return null;
    }
}

当我尝试通过以下方式调用此方法时,出现错误:

GetFileData(directory);

There is no argument given that corresponds to the required formal parameter 'columnName' of 'IExcelDataExtractor.GetFileData(string, string)'

当我这样称呼它时,它可以工作:

GetFileData(directory, null);

所以我有两个问题:

标签: c#

解决方案


在方法声明中的变量后面加上 = null 有什么作用?

它在调用方法时是可选的。所以你可以这样调用这个方法:

GetFileData("path", "columnName")

或者像这样:

GetFileData("path")

两者都是有效的。在第二种情况下,columnName将只是空。

如果我在调用此方法时可能仍需要发送相应的 null,为什么还要这样做?

希望我已经回答了?:)

除了使用NULL你还可以使用一个值......

GetFileData(string directoryPath, string columnName = "foobar")

在这种情况下,如果在调用时没有提供“foobar”,则默认值将是“foobar”。

编辑:

啊! IExcelDataExtractor. 某处有一个需要第二个参数的接口。你能告诉我们那个界面吗?

编辑2:

IExcelDataExtractor是一个接口。接口就像合同。任何实现它的类都必须具有在接口中创建的方法。

在内部IExcelDataExtractor,方法 `GetFileData(string, string)' 没有将第二个字符串定义为可选。这意味着即使实际方法可能会尝试使其成为可选方法,但它不能覆盖其在 IExcelDataExtractor 中的原始定义(即:契约)。

这就是为什么在GetFileData没有第二个参数的情况下调用时会出现错误的原因。


推荐阅读