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
(更多信息请参见)“显然不是这样”请详细说明您在这里的意思。仅基于该签名,第二个参数是可选的。如果您尝试调用它时它不是可选的,