【问题标题】:How would you refactor code with many bool fields?您将如何重构具有许多 bool 字段的代码?
【发布时间】:2021-12-30 12:01:50
【问题描述】:

例如,我有几种可能的逻辑组合,我需要确定哪些是正确的并根据结果执行操作。

public bool VerificationConnection(Transport objectFirst, Transport objectSecond) 
{
   bool isCarFirst = objectFirst is Car;
   bool isMotorcycleFirst = objectFirst is Motorcycle;
   
   bool isCarSecond = objectSecond is Car;
   bool isMotocycleSecond = objectSecond is Motorcycle;

   if(isCarFirst && isCarSecond) 
   {
      //do something
   }
   if(isCarFirst && isMotocycleSecond) 
   {
     //do something
   }
   if(isMotocycleFirst && isCarSecond) 
   {
     //do something
   }

   return true;
}

【问题讨论】:

  • 你有多少个布尔字段?只有两个?
  • @jira 目前只有两个,但可能会更快。

标签: c# refactoring


【解决方案1】:

您可以在 switch 语句中使用方便的 pattern matching (C# 7.0 - C# 10.0)。这在一个元组模式中组合了两种类型模式:

switch ((objectFirst, objectSecond)) {
    case (Car, Car):
        DoSomething();
        break;
    case (Car, Motorcycle):
        DoSomething();
        break;
    case (Motorcycle, Car):
        DoSomething();
        break;
    case (Motorcycle, Motorcycle):
        DoSomething();
        break;
}

如果你需要强类型的值,你可以使用声明模式;但是,这也可能是一个提示,即您的代码没有最佳地使用面向对象的原则。

switch ((objectFirst, objectSecond)) {
    case (Car c1, Car c2):
        DoSomething(c1, c2);
        break;
    case (Car c, Motorcycle m):
        DoSomething(c, m);
        break;
    case (Motorcycle m, Car c):
        DoSomething(m, c);
        break;
    case (Motorcycle m1, Motorcycle m2):
        DoSomething(m1, m2);
        break;
}

如果 switch 语句返回一个值,则使用 switch expression 代替。

var value = (objectFirst, objectSecond) switch {
    (Car c1, Car c2) => GetValue(c1, c2),
    (Car c, Motorcycle m) => GetValue(c, m),
    (Motorcycle m, Car c) => GetValue(m, c),
    (Motorcycle m1, Motorcycle m2) => GetValue(m1, m2),
    _ => null
};

【讨论】:

  • 出于好奇,为什么不ArgumentOutOfRangeException
  • throw expression 是一种可能性。由于问题没有透露足够的细节,因此我们无法决定在这里处理默认情况的最佳方法是什么。
【解决方案2】:

您可以使用调度表。对于具有两个布尔字段的用例,代表字典或类似的东西可能就足够了。

Dictionary<(bool, bool), Delegate> dispatch = new Dictionary<(bool, bool), Delegate>();

dispatch[(true, true)] = new Action(() => Console.WriteLine("Hello"));
dispatch[(true, false)] = new Action<string>(s => Console.WriteLine(s));

dispatch[(true, true)].DynamicInvoke();
dispatch[(true, false)].DynamicInvoke("World");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-08
    • 1970-01-01
    • 2018-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多