我有一些看起来像这样的方法调用
EAccessViolation
每个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);
}
,以便我可以定义一个操作和条件列表,然后迭代它们。
类似的东西:
if
SOLUTION:
感谢@ peter-duniho的回答,我放弃了创建var sections = new Dictionary<bool, Func<Task>>()
{
{
SectionContainedWithin(args, RegisterSection.StudentPersonalData),
() => schoolRegister.StudentPersonalData = await _sectionGeneratorsProvider.StudentPersonalDataGenerator.GenerateAsync(args);
},
// More generating here ...
}
foreach(var item in sections)
{
if(item.Key)
{
await item.Value();
}
}
的想法并将其替换为Dictionary<bool, Func<Task>>
,因为它更有意义。
多个键,不仅是两个真/假。
这就是我最终的结果
IReadOnlyDictionary<RegisterSection, Func<RegisterXml, RegisterGenerationArgs, Task>>
答案 0 :(得分:1)
如果我正确理解代码示例,字典确实不适合这项工作。您似乎只使用它来存储值对;您没有使用字典的主要功能,即能够将您已知的键值映射到另一个值。
此外,您提议的代码示例无法正常工作,因为您需要args
值才能评估SectionContainedWithin()
调用。即使您试图在args
有效且可用于初始化字典的上下文中声明字典,您也会遇到问题,即它使密钥类型为bool
,这意味着您最多只能在字典中有两个条目,并且无法实际处理SectionContainedWithin()
方法返回true
的所有组合。
如果没有一个好的Minimal, Complete, and Verifiable code example能清楚地表明你正在做什么,那么就不可能确切地知道你究竟需要什么。但它看起来像这样:
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.
}
然后你可以做类似的事情:
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));