C# 方法声明中的变量=null?它是什么意思?这个方法是如何调用的?

C# 方法声明中的变量=null?它是什么意思?这个方法是如何调用的?,c#,C#,今天在浏览一些代码时,我偶然发现了以下方法声明 public List GetFileData(string directoryPath,string columnName=null) 我构建了类似的东西,并尝试使用单个参数调用此方法,因为我声明了columnName=null,所以我可以选择在这里发送一个参数。显然不是这样 我做了一个界面 public interface IExcelDataExtractor { List<Tuple<DataTable, string&

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

public List GetFileData(string directoryPath,string columnName=null)

我构建了类似的东西,并尝试使用单个参数调用此方法,因为我声明了
columnName=null
,所以我可以选择在这里发送一个参数。显然不是这样

我做了一个界面

public interface IExcelDataExtractor
{
    List<Tuple<DataTable, string>> GetFileData(string directoryPath, string columnName);
}
公共接口IExcelDataExtractor
{
列出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;
    }
}
公共类ExcelDataExtractor:IExcelDataExtractor
{
/// 
///循环遍历给定目录中的每个文件并提取数据
/// 
///要在其中查找excel文件的目录
///提取器将查找列名存在的工作表,以便在多个工作表的情况下从中提取数据,或者在传递null的情况下从单个工作表中提取数据
公共列表GetFileData(string directoryPath,string columnName=null)
{
//启动元组列表
List dataTableWithFileName=新列表();
//使用*.xls*上的筛选器循环遍历目录中的每个文件,这将捕获.xls和.xlsx
foreach(Directory.EnumerateFiles(directoryPath,*.xls*)中的字符串文件)
{
数据集ds;
数据表dt;
ds=读取(文件);
dt=ExtractDataByColumn(ds,columnName);
如果(dt为空)
{
返回null;
}
dataTableWithFileName.Add(Tuple.Create(dt,file));
}
返回dataTableWithFileName;
}
/// 
///读取excel文件并将数据发送到数据集,每个工作表都是工作表中的数据表
/// 
///要打开并添加到数据集的文件
///从文件中返回数据集
私有数据集读取(字符串文件)
{
使用(var stream=File.Open(File,FileMode.Open,FileAccess.Read))
{
使用(IExcelDataReader=ExcelReaderFactory.CreateReader(流))
{
var conf=新的ExcelDataSetConfiguration
{
ConfigureDataTable=\u=>new ExcelDataTableConfiguration
{
UseHeaderRow=true
}
};
返回reader.AsDataSet(conf);
}
}
}
私有数据表ExtractDataByColumn(数据集数据集,字符串columnName=null)
{
如果(!string.IsNullOrEmpty(columnName))
{
foreach(dataSet.Tables中的DataTable表)
{
DataColumnCollection columns=table.columns;
if(columns.Contains(columnName))
{
返回表;
}
}
}
其他的
{
//如果没有给出columnName&存在超过1张表,我们希望此操作失败,否则返回单个表
foreach(dataSet.Tables中的DataTable表)
{
如果(dataSet.Tables.Count>1)
{
返回null;
}
其他的
{
返回表;
}
}
}
返回null;
}
}
当我尝试以以下方式调用此方法时,会出现错误:

GetFileData(目录)

没有给定与“IExcelDataExtractor.GetFileData(string,string)”的必需形式参数“columnName”对应的参数

当我这样称呼它时,它起作用了:

GetFileData(目录,空)

所以我有两个问题:

  • =null
    放在方法声明中的变量后面做什么
  • 如果我在调用此方法时仍然需要发送相应的
    null
    ,为什么还要这样做

在方法声明中的变量后放置=null有什么作用?

在调用该方法时,它使其成为可选的。因此,您可以这样调用此方法:

GetFileData("path", "columnName")
GetFileData("path")
或者像这样:

GetFileData("path", "columnName")
GetFileData("path")
两者都是有效的。在第二种情况下,
columnName
将仅为null

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

希望我已经回答了这个问题?:)

除了使用
NULL
之外,还可以使用一个值

GetFileData(string directoryPath, string columnName = "foobar")
在这种情况下,如果调用时未提供任何值,“foobar”将是默认值

编辑:

啊!<代码>IExcelDataExtractor
。 某个地方有一个接口需要第二个参数。你能给我们看看这个界面吗

编辑2:

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

IExcelDataExtractor
中,“GetFileData(string,string)”方法没有将第二个字符串定义为可选字符串。这意味着,即使实际的方法可能会尝试使其成为可选的,它也不能在IExcelDataExtractor中重写其原始定义(即:contract)


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

是否存在编译器错误?只需将其称为
GetFileData(“”),它就可以正常工作它应该是可选的(未指定时使用默认值)。但是对于C#8.0来说,这可能是错误的。因为声明可能应该是
string?columnName=null
(更多信息请参见)“显然不是这样”请详细说明您在这里的意思。仅基于该签名,第二个参数是可选的。如果您尝试调用它时它不是可选的,