C#代码可读性问题

本文关键字:问题 可读性 代码 | 更新日期: 2023-09-27 17:58:05

        int scalar = creature is SpecialCreature ? (creature.IsAwesome ? 700 : 500) : (creature is NotSoNormalCreature ? 
            (creature.IsAwesome ? (creature is IGreatCreature ? 450 : 280) : 240) : 
            (creature.IsAwesome ? (creature is IGreatCreature ? 300 : 200) : 160));

我应该如何编写代码以使其可读性更强?

我想只是建立if,但后来我想做一些"ConditionFactory"怎么样?这有意义吗?还是对于这样一项简单的任务来说太复杂了?

int scalar;
if (creature is SpecialCreature)
{
    scalar = creature.IsAwesome ? 700 : 500;
}
else if (creature is NotSoNormalCreature)
{
    if (creature.IsAwesome)
    {
        scalar = creature is IGreatCreature ? 450 : 280;
    }
    else
    {
        scalar = 240;
    }
}
else
{
    if (creature.IsAwesome)
    {
        scalar = creature is IGreatCreature ? 300 : 200;
    }
    else
    {
        scalar = 160;
    }
}

C#代码可读性问题

不完全确定你要做什么,但由于你使用的是基类型继承链,你可能会选择做一些类似的事情

interface ICreature
{
    bool IsAwesome { get; set; }
    int GetScalar();
}
abstract class Creature : ICreature
{
    public bool IsAwesome { get; set; }
    public virtual int GetScalar()
    {
        return 160;
    }
}
class SpecialCreature : Creature
{
    public override int GetScalar()
    {
        return this.IsAwesome ? 700 : 500;
    }
}
class NotSoNormalCreature : Creature
{
    public override int GetScalar()
    {
        return this.IsAwesome ? 450 : 280;
    }
}
// more ICreatures...

这将允许你让生物实现自己的逻辑来确定标量,而你的消耗代码可能会失去关心的复杂性。

ICreature creature = GetCreatureFromSomewhere();
int scalar = creature.GetScalar();

这不是您所需要的,但当条件可以解析为Or或And的列表时,我使用Extension方法来实现这种链方法。

类似的东西

if (true.IfOr(condition1 == a, condition2 == b) 
{ 
  something(); 
}

扩展方法很简单:

public static bool IfOr(this bool result, params bool[] tests)
{
  foreach (bool test in tests)
    if (!test)
      return !result;
  return result;
}

另一种可行的方法是使用.net中的Predicate委托,并定义一个执行单个逻辑单元的方法列表,尽管它可能不是很理想。然后可以用lambda替换嵌套的三级运算符。对不起,我手头没有这方面的代码示例。

不过,最后,有时没有什么比一个好的旧switch语句更好的了。我相信.Net倾向于将这些代码编译为跳转表,所以只要你先用最可分性的表来排列测试,那么你实际上就可以得到性能良好、可读性强的代码。它是可维护的,而不是用技巧隐藏逻辑或实现。

我认为真正的问题是对"配置数据"进行硬编码。如果你在哪里说,把这些"设置"撕下来,放进一个XML配置文件中,那么整个混乱难道不会消失吗?

在你调整各种配置以使游戏更具可玩性之前,这似乎也有些过头了。。。单独的配置文件允许您轻松播放(和还原(。


编辑:

顺便说一下,我会把嵌套的terniary语句格式化如下。。。以使其可读性更强。

int scalar =
  creature is SpecialCreature
  ? creature.IsAwesome ? 700 : 500
  : creature is NotSoNormalCreature
    ? creature.IsAwesome
      ? creature is IGreatCreature ? 450 : 280
      : 240
    : creature.IsAwesome
      ? creature is IGreatCreature ? 300 : 200
      : 160
;

干杯。基思。

这就是我重新编写代码并使其可读的方法

// Original code spread apart
int scalar = creature is SpecialCreature ? (
    creature.IsAwesome ? 700 : 500
) : (
    creature is NotSoNormalCreature ? (
        creature.IsAwesome ? (
            creature is IGreatCreature ? 450 : 280
        ) : 240
    ) : (
        creature.IsAwesome ? (
            creature is IGreatCreature ? 300 : 200
        ) : 160
    )
);
// Readable code with hybrid if() and ? :
if (creature is SpecialCreature)
{
    scalar = creature.IsAwesome ? 700 : 500;
}
else if (creature is NotSoNormalCreature)
{
    if (creature.IsAwesome)
    {
        scalar = creature is IGreatCreature ? 450 : 280;
    }
    else
    {
        scalar = 240;
    }
}
else
{
    if (creature.IsAwesome)
    {
        scalar = creature is IGreatCreature ? 300 : 200;
    }
    else
    {
        scalar = 160;
    }
}

如果可能的话,我建议在每个类中移动此计算,并为不同的分支重写。

好的旧货怎么样:

if (creature is SpecialCreature)
{
    scalar=getSpecialCreatureScalar(creature);
}
else if (creature is NotSoNormalCreature)
{
    scalar=getNotSoNormalCreatureScalar(creature);
}
else
{
    scalar=getScalar(creature);
}

然后

int GetSpecialCreatureScalar(SpecialCreature creature)
{
    return creature.IsAwesome ? 700 : 500;
}   
int GetNotSoNormalCreatureScalar(NotSoNormalCreature creature)
{
    if (creature.IsAwesome)
    {
        return creature is IGreatCreature ? 450 : 280;
    }
    else
    {
        return 240;
    }
}   
int GetScalar(Creature creature)
{
    if (creature.IsAwesome)
    {
        return creature is IGreatCreature ? 300 : 200;
    }
    else
    {
        return 160;
    }
}  

赋予if的含义。制作不同的IMO.