【问题标题】:Ternary operator difficult to read三元运算符难以阅读
【发布时间】:2026-01-12 09:30:01
【问题描述】:

有什么建议可以让下面的查询更“可读”吗?

var result = result
                .OrderBy(a =>
                    (conditionA) ?
                    valueA :
                    (conditionB ? valueB :
                    (conditionC ?
                    (conditionD ?
                    valueC : valueD) :
                    valueE)));

条件和值的长代码难以阅读。

【问题讨论】:

  • 添加适当的缩进并将冒号:与其对应的questino标记?对齐
  • ternary-operator: "三元运算符是 any 运算符,它接受三个参数。对于三元条件运算符?...:,请使用[tag:conditional-operator] 。” (我的重点
  • 更好的是删除所有条件。您在代码中添加OrderByThenBy 语句,它们只是函数。如果要动态指定排序字段,可以在 LINQ 中轻松完成
  • 视情况而定。对于简单的条件,我只需重新对齐代码。对于复杂的条件,我会考虑提取一个委托
  • 实际上,@PanagiotisKanavos,无法使用OrderBy / ThenBy 链实现此效果,因为根据条件,比较可能最终将left.valueAright.valueC 或任何其他进行比较组合。

标签: c# conditional-operator


【解决方案1】:

有几种方法可以提高代码的可读性。

缩进

一种方法是以稍微不同的方式缩进代码,但这只会稍微提高可读性:

var result = result.OrderBy(a =>
    conditionA ? valueA :
    conditionB ? valueB :
    conditionC ? conditionD ? valueC :
                              valueD :
                valueE);

如果,否则

您还可以将这些三元运算符转换为更易读的ifelse 链。

var result = Result.OrderBy(a => {
    if (conditionA)
    {
        return valueA;
    }
    else if (conditionB)
    {
        return valueB;
    }
    else if (conditionC)
    {
        if (conditionD)
        {
            return valueC;
        }
        else
        {
            return valueD;
        }
    }
    else
    {
        return valueE;
    }
});

IComparer

一种选择是编写您自己的IComparer<> 实现并将其传递给OrderBy 方法。我不知道你的对象是什么类型或者你的代码中的键是什么类型,所以我假设string键。

public class MyClassComparer : IComparer<MyClass>
{
    public int Compare(MyClass x, MyClass y)
    {
        string xKey = getKey(x);
        string yKey = getKey(y);
        return string.Compare(xKey, yKey);
    }

    private string getKey(MyClass item)
    {
        if (item.conditionA)
        {
            return item.valueA;
        }
        else if (item.conditionB)
        {
            return item.valueB;
        }
        else if (item.conditionC)
        {
            if (item.conditionD)
            {
                return item.valueC;
            } 
            else
            {
                return item.valueD;
            }
        }
        else
        {
            return item.valueE;
        }
    }
}

扩展方法

最后一个选择是将您的代码移动到扩展方法:

public static class MyClassExtensions
{
    public static string GetSortingKey(this MyClass item)
    {
        if (item.conditionA)
        {
            return item.valueA;
        }
        else if (item.conditionB)
        {
            return item.valueB;
        }
        else if (item.conditionC)
        {
            if (item.conditionD)
            {
                return item.valueC;
            } 
            else
            {
                return item.valueD;
            }
        }
        else
        {
            return item.valueE;
        }
    }
}

使用最后一个选项,您对OrderBy 的调用很简单:

result.OrderBy(a => a.GetSortingKey())

【讨论】:

  • 我也会这样做。即使你知道所有的解析规则,多个三元运算符也很难理解。