You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#机场停机位规划程序多条件判断优化方案咨询

Hey there! I totally get the headache of tangled nested if statements for your airport gate assignment program—they’re not just a pain to read and maintain, but they can also slow down as you add more conditions like aircraft size, domestic/international status, and terminal assignments. Let’s break down several efficient, clean alternatives that’ll make your code more scalable and easier to tweak later on.

1. Strategy Pattern (Clean, Extensible)

This is my go-to for scenarios where you have distinct condition sets that map to specific behaviors. The idea is to encapsulate each gate assignment logic into its own "strategy" class, then pick the right strategy based on your flight’s attributes instead of nesting ifs.

First, define a common interface for all assignment strategies:

public interface IGateAssignmentStrategy
{
    bool IsMatch(Flight flight);
    Gate AssignGate(Flight flight);
}

// Your core Flight and Gate models (example)
public class Flight
{
    public AircraftType AircraftType { get; set; } // Large/Small
    public bool IsInternational { get; set; }
    public Terminal Terminal { get; set; } // T1/T2/T3
}

public enum AircraftType { Large, Small }
public enum Terminal { T1, T2, T3 }
public class Gate { public string Id { get; set; } }

Then create concrete strategies for each condition combination:

public class DomesticLargeT1Strategy : IGateAssignmentStrategy
{
    public bool IsMatch(Flight flight)
    {
        return !flight.IsInternational && flight.AircraftType == AircraftType.Large && flight.Terminal == Terminal.T1;
    }

    public Gate AssignGate(Flight flight)
    {
        // Logic for assigning large domestic flights to T1 gates
        return new Gate { Id = "T1-L-01" };
    }
}

public class InternationalSmallT3Strategy : IGateAssignmentStrategy
{
    public bool IsMatch(Flight flight)
    {
        return flight.IsInternational && flight.AircraftType == AircraftType.Small && flight.Terminal == Terminal.T3;
    }

    public Gate AssignGate(Flight flight)
    {
        return new Gate { Id = "T3-S-12" };
    }
}

Finally, use a context to pick the right strategy at runtime:

public class GateAssigner
{
    private readonly List<IGateAssignmentStrategy> _strategies;

    public GateAssigner(List<IGateAssignmentStrategy> strategies)
    {
        _strategies = strategies;
    }

    public Gate AssignGate(Flight flight)
    {
        var matchingStrategy = _strategies.FirstOrDefault(s => s.IsMatch(flight));
        if (matchingStrategy == null)
            throw new InvalidOperationException("No matching assignment strategy found.");
        
        return matchingStrategy.AssignGate(flight);
    }
}

The best part? When you add a new condition (like a new terminal or aircraft type), you just create a new strategy class—no messing with existing nested ifs.

2. Rule Engine (Dynamic Rule Management)

If you expect rules to change frequently (e.g., airport updates their gate policies), a lightweight rule engine lets you define and manage rules without rewriting core code. You can roll your own simple version instead of using heavy external libraries.

First, define a rule structure:

public class GateAssignmentRule
{
    public Func<Flight, bool> Condition { get; set; }
    public Func<Flight, Gate> Action { get; set; }
}

Then build a rule engine to evaluate your rules:

public class RuleBasedGateAssigner
{
    private readonly List<GateAssignmentRule> _rules;

    public RuleBasedGateAssigner(List<GateAssignmentRule> rules)
    {
        _rules = rules;
    }

    public Gate AssignGate(Flight flight)
    {
        var matchingRule = _rules.FirstOrDefault(r => r.Condition(flight));
        if (matchingRule == null)
            throw new InvalidOperationException("No matching rule found.");
        
        return matchingRule.Action(flight);
    }
}

Initialize your rules like this:

var rules = new List<GateAssignmentRule>
{
    new GateAssignmentRule
    {
        Condition = f => !f.IsInternational && f.AircraftType == AircraftType.Large && f.Terminal == Terminal.T1,
        Action = f => new Gate { Id = "T1-L-01" }
    },
    new GateAssignmentRule
    {
        Condition = f => f.IsInternational && f.AircraftType == AircraftType.Small && f.Terminal == Terminal.T3,
        Action = f => new Gate { Id = "T3-S-12" }
    }
};

var assigner = new RuleBasedGateAssigner(rules);

You can even load rules from a config file later if you want—super flexible.

3. Dictionary Mapping (Fast, Direct Lookup)

If your condition combinations are fixed and discrete (no dynamic rules), a dictionary with composite keys is blazingly fast. You can use a ValueTuple or a custom struct as the key to represent your condition set.

Example with ValueTuple:

public class DictionaryGateAssigner
{
    private readonly Dictionary<(bool IsInternational, AircraftType Type, Terminal Terminal), Func<Flight, Gate>> _assignmentMap;

    public DictionaryGateAssigner()
    {
        _assignmentMap = new Dictionary<(bool, AircraftType, Terminal), Func<Flight, Gate>>
        {
            { (false, AircraftType.Large, Terminal.T1), f => new Gate { Id = "T1-L-01" } },
            { (true, AircraftType.Small, Terminal.T3), f => new Gate { Id = "T3-S-12" } },
            // Add all other condition combinations here
        };
    }

    public Gate AssignGate(Flight flight)
    {
        var key = (flight.IsInternational, flight.AircraftType, flight.Terminal);
        if (!_assignmentMap.TryGetValue(key, out var assignAction))
            throw new InvalidOperationException("No gate assignment found for this flight.");
        
        return assignAction(flight);
    }
}

This is O(1) lookup time, which is as efficient as it gets. Perfect if your conditions don’t change often.

4. LINQ Expression Trees (Advanced Dynamic Conditions)

For super dynamic scenarios (e.g., letting users define custom rules via a UI), LINQ expression trees let you compile conditions at runtime into efficient delegates. This is overkill for simple cases, but great for complex, user-driven rule sets.

Here’s a quick example of compiling a condition:

// Build a dynamic condition for international large flights in T2
var param = Expression.Parameter(typeof(Flight), "f");
var condition = Expression.Lambda<Func<Flight, bool>>(
    Expression.AndAlso(
        Expression.AndAlso(
            Expression.Property(param, nameof(Flight.IsInternational)),
            Expression.Equal(Expression.Property(param, nameof(Flight.AircraftType)), Expression.Constant(AircraftType.Large))
        ),
        Expression.Equal(Expression.Property(param, nameof(Flight.Terminal)), Expression.Constant(Terminal.T2))
    ),
    param
);

var compiledCondition = condition.Compile();
bool matches = compiledCondition(new Flight { IsInternational = true, AircraftType = AircraftType.Large, Terminal = Terminal.T2 });

You can combine this with a rule engine to let users build their own conditions without touching code.


Which One Should You Pick?

  • Use Strategy Pattern if you want clean, testable code and plan to add new condition types regularly.
  • Use Rule Engine if rules need to be updated frequently (even at runtime) without recompiling.
  • Use Dictionary Mapping for the fastest possible lookup when conditions are fixed and discrete.
  • Use Expression Trees only if you need fully dynamic, user-defined conditions.

内容的提问来源于stack exchange,提问作者H.Avni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:39:22