user17664091
user17664091

Reputation:

Refactoring big if else stament in C# code

I have four of this really long if-else code. How can I refactor this code?

if (objectcameraangle > 140)
{
  if (Vector3.Distance(joint1, joint2) > 0.5)
  {
    Rfootikcontroller.transform.Translate((scx / 10000), scy / 10000, 0);
  }
  else
  {
    Rfootikcontroller.transform.Translate((scx / 800), scy / 800, 0);
  }
}
else if (objectcameraangle < 35)
{
  if (Vector3.Distance(joint1, joint2) > 0.5)
  {
    Rfootikcontroller.transform.Translate((-scx / 10000), scy / 10000, 0);
  }
  else
  {
    Rfootikcontroller.transform.Translate((-scx / 800), scy / 800, 0);
  }
}
else if (objectcameraangle > 35 && objectcameraangle < 140 && signed > 0)
{
  if (Vector3.Distance(joint1, joint2) > 0.5)
  {
    Rfootikcontroller.transform.Translate(0, scy / 10000, (-scx / 10000));
  }
  else
  {
    Rfootikcontroller.transform.Translate(0, scy / 800, (-scx / 800));
  }
}

How I can rewrite it to something more nice . Trying to learn here something new . Thanks for help.

Upvotes: 0

Views: 139

Answers (3)

Nicholas Carey
Nicholas Carey

Reputation: 74375

Looking at your code I see two things:

  • Almost all of that code is for all intents and purposes, simply assigning 4 different variables, and

  • There are fall-through/no-op conditions: When scx is exactly 35 or 140, or signed is non-positive.

I would isolate the assignment of each variable and invoke the Translate() method at the end, thus:

int angle = objectcameraangle // because, too many letters (and runtogetherwords)

int d = Vector3Distance > 0.5
      ? 10000
      :   800
      ;
int? x = angle > 140                              ?   scx / d
       : angle <  35                              ? - scx / d
       : angle >  35 && angle < 140 && signed > 0 ? 0
       : null // TODO what happens when objectcameraangle is exactly 35 or 140, or is signed <= 0?
       ;
int? y = angle > 140                              ?   scy / d
       : angle <  35                              ?   scy / d
       : angle >  35 && angle < 140 && signed > 0 ?   scy / d
       : null // TODO what happens when objectcameraangle is exactly 35 or 140, or is signed <= 0?
       ;
int? z = angle > 140 ? 0
       : angle <  35 ? 0
       : angle >  35 && angle < 140 && signed > 0 ? - scx / d
       : null // TODO what happens when objectcameraangle is exactly 35 or 140, or is signed <= 0?
       ;

// Wrapped in a guard clause to protect against the fall-through condition(s) noted above
if ( x != null && y != null && z != null ) {
  Rfootikcontroller.transform.Translate( x, y, z );
}

You could then extract the logic for each of the 4 variable assignments out to individual methods, making them simple and easily testable. That would give you something like this:

static int SelectDistance( double v3Distance )
{
  return Vector3Distance > 0.5
       ? 10000
       :   800
       ;
}

static int SelectValue( angle int , signed int, v1 int, v2 int , v3 int , v4 int)
{
  return angle > 140                             ? v1
       : angle <  35                             ? v2
       : angle >  35 && angle < 140 && signe > 0 ? v3
       :                                           v4
       ;
}
.
.
.
int  angle = objectcameraangle // because, too many letters (and runtogetherwords)

int  d = SelectDistance( Vector3Distance );
int? x = SelectValue( angle, signed, scx/d, -scx/d,      0, null );
int? y = SelectValue( angle, signed, scy/d,  scy/d,  scy/d, null );
int? z = SelectValue( angle, signed,     0,      0, -scx/d, null );

// Wrapped in a guard clause to protect against the fall-through condition(s) noted above
if ( x != null && y != null && z != null ) {
  Rfootikcontroller.transform.Translate( x, y, z );
}

Upvotes: 0

Mass Dot Net
Mass Dot Net

Reputation: 2258

If you're using a recent version of C# (8.0+ I think?), you can try something like this:

var denominator = (Vector3.Distance(joint1, joint2) > 0.5 ? 10000 : 800);

switch (true) {
    case var _ when objectcameraangle > 140:
        Rfootikcontroller.transform.Translate((scx / denominator), scy / denominator, 0);
        break;
    case var _ when objectcameraangle < 35:
        Rfootikcontroller.transform.Translate((-scx / denominator), scy / denominator, 0);
        break;
    case var _ when objectcameraangle > 35 && objectcameraangle < 140 && signed > 0:
        Rfootikcontroller.transform.Translate(0, scy / denominator, (-scx / denominator));
        break;
}

Hopefully that compiles... I don't have all of your objects available, obviously, so I couldn't check myself.

Upvotes: 0

Victor
Victor

Reputation: 2371

Something like this?

var distance = Vector3.Distance(joint1, joint2);
var divisor = distance > 0.5 ? 10000 : 800;

var scx2 = scx / divisor;
var scy2 = scy / divisor;

if (objectcameraangle < 35)
{
    Rfootikcontroller.transform.Translate(-scx2, scy2, 0);
}
else if (objectcameraangle < 140)
{
    if (signed > 0)
        Rfootikcontroller.transform.Translate(0, scy2, -scx2);
}
else
{
    Rfootikcontroller.transform.Translate(scx2, scy2, 0);
}

Upvotes: 1

Related Questions