在 C# 代码中重构大型 if else 语句
Refactoring big if else stament in C# code
我有四个非常长的 if-else 代码。我该如何重构这段代码?
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));
}
}
如何将它重写为更好的东西。想在这里学习一些新东西。感谢您的帮助。
是这样的吗?
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);
}
如果您使用的是最新版本的 C#(我认为是 8.0+?),您可以尝试如下操作:
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;
}
希望能编译...显然,我没有你所有的可用对象,所以我无法检查自己。
查看您的代码,我发现了两点:
几乎所有的代码都是为了所有的意图和目的,只需分配 4 个不同的变量,并且
有fall-through/no-op个条件:当scx
正好是35
或140
,或signed
是non-positive.
我会隔离每个变量的赋值并在最后调用 Translate()
方法,因此:
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 );
}
然后您可以将 4 个变量赋值中的每一个的逻辑提取到单独的方法中,使它们变得简单且易于测试。那会给你这样的东西:
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 );
}
我有四个非常长的 if-else 代码。我该如何重构这段代码?
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));
}
}
如何将它重写为更好的东西。想在这里学习一些新东西。感谢您的帮助。
是这样的吗?
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);
}
如果您使用的是最新版本的 C#(我认为是 8.0+?),您可以尝试如下操作:
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;
}
希望能编译...显然,我没有你所有的可用对象,所以我无法检查自己。
查看您的代码,我发现了两点:
几乎所有的代码都是为了所有的意图和目的,只需分配 4 个不同的变量,并且
有fall-through/no-op个条件:当
scx
正好是35
或140
,或signed
是non-positive.
我会隔离每个变量的赋值并在最后调用 Translate()
方法,因此:
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 );
}
然后您可以将 4 个变量赋值中的每一个的逻辑提取到单独的方法中,使它们变得简单且易于测试。那会给你这样的东西:
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 );
}