如何使用异步方法调用将一组if条件转换为Dictionary?

时间:2016-08-02 12:32:46

标签: c# dictionary async-await

我有一些看起来像这样的方法调用

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>>

1 个答案:

答案 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));