C#传递带有参数的Func,传递时设置1个参数,其他设置在里面
C# passing Func with parameters where 1 parameter is set while passing and the others are set inside
你好创建了这个方法来读取 excel:
public static Dictionary<int, TreeItemModel> ExcelReader(FileUploadModel upload,
Func<Dictionary<int, string>, Row, object, Action> func)
{
try
{
var dict = new Dictionary<int, TreeItemModel>();
using (var doc = SpreadsheetDocument.Open(upload.Stream, false))
{
var workbookPart = doc.WorkbookPart;
var worksheetPart = workbookPart.WorksheetParts.First();
var sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();
var stringTable = LoadSharedStringDictionarySax(workbookPart.SharedStringTablePart);
foreach (var r in sheetData.Elements<Row>())
{
func(stringTable, r, dict);
}
}
upload.Stream.Close();
upload.UploadCompletion = 100;
return dict;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
throw;
}
}
我在其他class中这样调用这个方法:
private async Task OnFilesDropped(FileUploadModel upload)
{
var dict = new Dictionary<int, TreeItemModel>();
OfficeHelper.ExcelExtension.ExcelReader(upload, ExcelToProjTree);
}
private static Action ExcelToProjTree(Dictionary<int, string> stringTable, Row r, Dictionary<int, TreeItemModel> dict)
{
//Some stuff
}
调用方法时设置了stringTable和r,但我想在调用ExcelReader时设置dict
有点像这样:
private async Task OnFilesDropped(FileUploadModel upload)
{
var dict = new Dictionary<int, TreeItemModel>();
OfficeHelper.ExcelExtension.ExcelReader(upload, () => ExcelToProjTree(dict));
}
可能吗?如果是,怎么做?
您可以使用Lazy<T>
private Lazy<Dictionary<int, TreeItemModel>> dict;
// Constructor
public YourClass()
{
this.dict = Lazy<Dictionary<int, TreeItemModel>>(
() => ExcelToProjTree(new Dictionary<int, TreeItemModel>()));
}
private async Task OnFilesDropped(FileUploadModel upload)
{
var dict = new Dictionary<int, TreeItemModel>();
// ExcelToProjTree Will be eveluated only now
OfficeHelper.ExcelExtension.ExcelReader(upload, () => dict.Value);
}
由于您将提供一个静态 object
参数参数(这被称为 partial application 顺便说一句),您需要将其从结果 [=15 的参数列表中删除=]类型:
public static Dictionary<int, TreeItemModel> ExcelReader(FileUploadModel upload,
Func<Dictionary<int, string>, Row, Action> func) { /* */ }
然后确保作为参数提供给 ExcelReader
的 lambda 也具有正确的签名(它仍然应该接受 Dictionary<int, string>
和 Row
参数):
OfficeHelper.ExcelExtension.ExcelReader(upload, (stringTable, row) => ExcelToProjTree(stringTable, row, dict));
最后更新函数的调用,以便您只传递前两个参数参数:
func(stringTable, r); // `dict` will automatically be bound inside of `func`
鉴于 func
仍然 returns 和 Action
,您可能想立即调用它:
func(stringTable, r)();
你好创建了这个方法来读取 excel:
public static Dictionary<int, TreeItemModel> ExcelReader(FileUploadModel upload,
Func<Dictionary<int, string>, Row, object, Action> func)
{
try
{
var dict = new Dictionary<int, TreeItemModel>();
using (var doc = SpreadsheetDocument.Open(upload.Stream, false))
{
var workbookPart = doc.WorkbookPart;
var worksheetPart = workbookPart.WorksheetParts.First();
var sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();
var stringTable = LoadSharedStringDictionarySax(workbookPart.SharedStringTablePart);
foreach (var r in sheetData.Elements<Row>())
{
func(stringTable, r, dict);
}
}
upload.Stream.Close();
upload.UploadCompletion = 100;
return dict;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
throw;
}
}
我在其他class中这样调用这个方法:
private async Task OnFilesDropped(FileUploadModel upload)
{
var dict = new Dictionary<int, TreeItemModel>();
OfficeHelper.ExcelExtension.ExcelReader(upload, ExcelToProjTree);
}
private static Action ExcelToProjTree(Dictionary<int, string> stringTable, Row r, Dictionary<int, TreeItemModel> dict)
{
//Some stuff
}
调用方法时设置了stringTable和r,但我想在调用ExcelReader时设置dict
有点像这样:
private async Task OnFilesDropped(FileUploadModel upload)
{
var dict = new Dictionary<int, TreeItemModel>();
OfficeHelper.ExcelExtension.ExcelReader(upload, () => ExcelToProjTree(dict));
}
可能吗?如果是,怎么做?
您可以使用Lazy<T>
private Lazy<Dictionary<int, TreeItemModel>> dict;
// Constructor
public YourClass()
{
this.dict = Lazy<Dictionary<int, TreeItemModel>>(
() => ExcelToProjTree(new Dictionary<int, TreeItemModel>()));
}
private async Task OnFilesDropped(FileUploadModel upload)
{
var dict = new Dictionary<int, TreeItemModel>();
// ExcelToProjTree Will be eveluated only now
OfficeHelper.ExcelExtension.ExcelReader(upload, () => dict.Value);
}
由于您将提供一个静态 object
参数参数(这被称为 partial application 顺便说一句),您需要将其从结果 [=15 的参数列表中删除=]类型:
public static Dictionary<int, TreeItemModel> ExcelReader(FileUploadModel upload,
Func<Dictionary<int, string>, Row, Action> func) { /* */ }
然后确保作为参数提供给 ExcelReader
的 lambda 也具有正确的签名(它仍然应该接受 Dictionary<int, string>
和 Row
参数):
OfficeHelper.ExcelExtension.ExcelReader(upload, (stringTable, row) => ExcelToProjTree(stringTable, row, dict));
最后更新函数的调用,以便您只传递前两个参数参数:
func(stringTable, r); // `dict` will automatically be bound inside of `func`
鉴于 func
仍然 returns 和 Action
,您可能想立即调用它:
func(stringTable, r)();