C# 如何将带有异步方法调用的if条件集转换为字典?
我有一些方法调用,如下所示C# 如何将带有异步方法调用的if条件集转换为字典?,c#,dictionary,async-await,C#,Dictionary,Async Await,我有一些方法调用,如下所示 if (SectionContainedWithin(args, RegisterSection.StudentPersonalData)) schoolRegister.StudentPersonalData = await _sectionGeneratorsProvider.StudentPersonalDataGenerator.GenerateAsync(args); if (SectionContainedWithin(args, Registe
if (SectionContainedWithin(args, RegisterSection.StudentPersonalData))
schoolRegister.StudentPersonalData = await _sectionGeneratorsProvider.StudentPersonalDataGenerator.GenerateAsync(args);
if (SectionContainedWithin(args, RegisterSection.StudentAttendances))
schoolRegister.StudentAttendances = await _sectionGeneratorsProvider.StudentMonthAttendancesGenerator.GenerateAsync(args);
if (SectionContainedWithin(args, RegisterSection.Grades))
schoolRegister.Grades = await _sectionGeneratorsProvider.GradesGenerator.GenerateAsync(args);
// More generating here ...
每个GenerateAsync
生成不同类型的对象
public interface IGenerator<TResult, in TArgs>
{
Task<TResult> GenerateAsync(TArgs args);
}
解决方案:
多亏了@peter duniho的回答,我放弃了创建字典的想法,取而代之的是IReadOnlyDictionary
,因为它更有意义。
多个关键点,而不仅仅是两个真/假
这就是我的结局
private IReadOnlyDictionary<RegisterSection, Func<RegisterXml, RegisterGenerationArgs, Task>> CreateSectionActionsDictionary()
{
return new Dictionary<RegisterSection, Func<RegisterXml, RegisterGenerationArgs, Task>>
{
{ RegisterSection.RegisterCover, async(reg, args) => reg.Cover = await _sectionGenerators.RegisterCoverGenerator.GenerateAsync(args) },
{ RegisterSection.StudentPersonalData, async(reg, args) => reg.StudentPersonalData = await _sectionGenerators.StudentPersonalDataGenerator.GenerateAsync(args)},
// Add more generating here ...
};
}
private async Task GenerateSectionsAsync(RegisterGenerationArgs args, RegisterXml reg)
{
foreach (var sectionAction in SectionActions)
if (SectionContainedWithin(args, sectionAction.Key))
await sectionAction.Value(reg, args);
}
private-IReadOnlyDictionary-CreateSectionActionsDictionary()
{
返回新词典
{
{RegisterSection.RegisterCover,async(reg,args)=>reg.Cover=wait_sectionGenerators.RegisterCoverGenerator.GenerateAsync(args)},
{RegisterSection.StudentPersonalData,async(reg,args)=>reg.StudentPersonalData=await{u sectionGenerators.StudentPersonalDataGenerator.GenerateAsync(args)},
//在这里添加更多。。。
};
}
专用异步任务GenerateSectionsAsync(RegisterGenerationArgs,RegisterXml reg)
{
foreach(SectionActions中的var sectionAction)
if(SectionContainedWithin(args,sectionAction.Key))
等待区段动作值(reg,args);
}
如果我正确理解了代码示例,那么字典确实不是这项工作的合适工具。您似乎只使用它来存储成对的值;您没有使用字典的主要功能,即能够将已知的键值映射到另一个值
此外,您建议的代码示例不起作用,因为您需要args
值来计算SectionContainedWithin()
调用。即使您试图在args
有效且可用于初始化词典的上下文中声明词典,您也会遇到这样的问题,即它使键类型bool
,这意味着您在词典中最多只能有两个条目,如果SectionContainedWithin()
方法返回true
,则无法实际处理所有组合
如果没有一个能清楚地显示你在做什么的好东西,就不可能确切地知道你到底需要什么。但它看起来是这样的:
struct SectionGenerator<TArgs>
{
public readonly RegisterSection RegisterSection;
public readonly Func<TArgs, Task> Generate;
public SectionGenerator(RegisterSection registerSection, Func<TArgs, Task> generate)
{
RegisterSection = registerSection;
Generate = generate;
}
}
SectionGenerator<TArgs>[] generators =
{
new SectionGenerator<TArgs>(RegisterSection.StudentPersonalData,
async args => schoolRegister.StudentPersonalData = await _sectionGeneratorsProvider.StudentPersonalDataGenerator.GenerateAsync(args);
// etc.
}
await Task.WhenAll(generators
.Where(g => SectionContainedWithin(args, g.RegisterSection))
.Select(g => g.Generate(args));
你就快到了,你只需要让lambdas异步
@svick:不太好。确实需要使lambdas异步
,但是字典还有更基本的问题:在填充字典时评估SectionContainedWithin()
方法不仅假设当时已知args
,而且一次字典中只有两个项,其中只有一个键值为true
。有关更多详细信息,请参阅我发布的答案。@PeterDuniho你是对的,我没有意识到字典
问题。你是对的,在这种情况下,字典不是最好的集合类型。相反,我会使用IEnumerable
或创建新的class
来存储bool
和func
对。我要改变这一点!关于提供MCV代码示例,第一个解决方案(一组if
s)有效,是我能想象到的最明显的方法。虽然这很难维持。明天我会回到这个问题上来。谢谢@皮兹基:我不明白存储bool
值的意义。如果您能够计算方法调用,那么您手头就有了args
值,可以直接调用相应的GenerateAsync()
方法。在这种情况下,您只需要存储返回的任务。如果手头没有args
值,则无法获取bool
值。不管怎样,在你的收藏中存储一个bool
是没有意义的。你是对的,现在对我来说也没有意义。谢谢你指出这一点。
foreach (SectionGenerator<TArgs> generator in generators)
{
if (SectionContainedWithin(args, generator.RegisterSection))
{
await generator.Generate(args);
}
}
await Task.WhenAll(generators
.Where(g => SectionContainedWithin(args, g.RegisterSection))
.Select(g => g.Generate(args));