【问题标题】:Neatest/most idiomatic way to rewrite this If in C#在 C# 中重写此 If 的最简洁/最惯用的方法
【发布时间】:2011-06-03 23:22:55
【问题描述】:

我有这个if-else 声明,它可以满足我的需求。正如你应该知道的那样,它的作用非常简单。

if (width != null && height != null)
{
    if (top != null && left != null)
    {
        ret.type = VMLDimensionType.full;
    }
    else
    {
        ret.type = VMLDimensionType.size;
    }
}
else
{
    if (top != null && left != null)
    {
        ret.type = VMLDimensionType.positon;
    }
    else
    {
        ret.type = VMLDimensionType.unset;
    }
}

enum 指的是:

private enum VMLDimensionType
{
    unset = 0,
    full = 1,
    size = 2,
    position = 3
}

它是如此简单,我相信有一种更简洁、更易读的方式来表达这一点。

NB 如果不是因为 VS 默认强加的荒谬的“每行一个大括号”规则,我可能不会这么烦恼。例如,在 VB 中,我可能会从这个代码块中丢失大约 10 行! (对此有什么想法吗?)

【问题讨论】:

  • 如果我没记错的话,VB.NET 版本会短 7 行,没有大括号的版本会短 12 行。
  • 你能发布VMLDimensionType枚举吗?如果它是一个 Flags 枚举,它可能会更简单。
  • @Ani 更新了枚举定义
  • @El:好吧,只需更改默认值即可。 VS 幸运地允许这样做。像这样将每个大括号放在额外的行上确实是 浪费并且不利于可读性(恕我直言)。

标签: c# refactoring code-snippets code-readability conditional-statements


【解决方案1】:

这个怎么样:

bool hasSize = width != null && height != null;
bool hasPosition = top != null && left != null;

if (hasSize && hasPosition)
{
    ret.type = VMLDimensionType.full;
}
else if (hasSize && !hasPosition)
{
    ret.type = VMLDimensionType.size;
}
else if (!hasSize && hasPosition)
{
    ret.type = VMLDimensionType.positon;
}
else
{
    ret.type = VMLDimensionType.unset;
}

【讨论】:

  • +1 我非常喜欢这个解决方案提供的可读性。它仍然很大,但这可能只是我习惯了所有这些大括号:)
  • @El Ronnoco 在单行语句中,您可以删除大括号 - 但我建议保留它们,因为它可以更轻松地合并源代码控制中的更改,并为您提供明确的分组,您的眼睛可以浏览.
  • @Will 是的,当我第一次开始使用 C# 时,我曾经省略了单行代码块的大括号。然后我不得不把其中一些做成两行代码块......
【解决方案2】:
bool hasPosition = (top != null && left != null);
bool hasSize = (width != null && height != null);

if (hasSize)
{
    ret.type = hasPosition ? VMLDimensionType.full : VMLDimensionType.size;
}
else
{
    ret.type = hasPosition ? VMLDimensionType.positon : VMLDimensionType.unset;
}

【讨论】:

  • 行数最少的编码并不是最好的恕我直言。具有清晰可读性的行数较少的代码使其成为最好的。这个符合要求。
  • +1 我喜欢它,实际上很好读。有点像从图表中读取。与其他人相似,但仍然......
  • 抱歉,我已将我接受的答案更改为 Ani 的,因为我喜欢他们使枚举反映正在发生的事情的逻辑的方式。
【解决方案3】:

这个呢:

if(width != null && height != null)
    ret.type = top != null && left != null ? VMLDimensionType.full : VMLDimensionType.size;
else
    ret.type = top != null && left != null ? VMLDimensionType.positon : VMLDimensionType.unset;

【讨论】:

  • 在我发布之前没有看到 Chibacity 的评论 :(
  • 是的,但不是最整洁的。他的 imo 更好
  • @1 啊,有点谦虚!
【解决方案4】:

一种选择是将VMLDimensionType 设为Flags 枚举:

[Flags]
enum VMLDimensionType
{
    Unset = 0,
    Size = 1,
    Position = 1 << 1,
    Full = Size | Position
}

然后:

ret.Type = VMLDimensionType.Unset;

if(width != null && height != null)
    ret.Type |= VMLDimensionType.Size;

if (top != null && left != null)
    ret.Type |= VMLDimensionType.Position;

【讨论】:

  • 嗯,我可能不得不更改我接受的答案 :) 这更有意义,因为枚举反映了实际逻辑......
  • @cibacity Full 当 Size 和 Position 都被设置时是隐式的。这就是它的美妙之处。执行逻辑 OR 可以实现这一点。
  • @El Ronnoco:该死的,我需要睡一觉——当然需要,我太密集了——哎呀!
  • 你为什么写1 &lt;&lt; 1而不是简单的2
  • @Oliver:你说得对,我能做到。这就是我通常编写标志枚举的方式。对我来说,它澄清了我们正在设置第二位(1 左移一位)。
【解决方案5】:

我想提取 GetDimensionType() 方法。 并使它不那么小,但更具可读性和自我描述性。

private VMLDimensionType GetDimensionType()
{
    bool hasSize = width != null && height != null;
    bool hasPosition = top != null && left != null;

    if (hasSize && hasPosition)
        return VMLDimensionType.full;

    if (hasSize)
        return VMLDimensionType.size;

    if (hasPosition)
        return VMLDimensionType.positon;

    return VMLDimensionType.unset;
}

用法:

ret.type = GetDimensionType();

【讨论】:

  • top,left,widthheight 来自哪里?还是他们作为成员被访问?
  • 是的,我想这是某个对象的成员。无论如何,如果它们不是,您可以将它们作为参数传递。
  • +1 表示中间函数返回。请注意,他们将所有其他解决方案的 else ifs 转换为更简单的 ifs 有多好。
猜你喜欢
  • 2010-12-06
  • 2021-09-29
  • 1970-01-01
  • 1970-01-01
  • 2014-07-05
相关资源
最近更新 更多