目前我有七个if语句类似于以下代码:
if(hit.collider.gameObject.tag == "Colour1" && start_time > look_at_time)
{
new_colour1.ChangeObjectMaterialColour(hit.collider.gameObject.renderer.material.color);
var colums = GameObject.FindGameObjectsWithTag("column");
foreach( GameObject c in colums)
c.GetComponent<MeshRenderer>().materials[1].color = new_colour1.orignalMaterial;
}
else if(hit.collider.gameObject.tag == "Colour2" && start_time > look_at_time)
{
new_colour2.ChangeObjectMaterialColour(hit.collider.gameObject.renderer.material.color);
var colums = GameObject.FindGameObjectsWithTag("column");
foreach( GameObject c in colums)
c.GetComponent<MeshRenderer>().materials[1].color = new_colour2.orignalMaterial;
}
每个语句大约有6行代码,占用了大量空间,读起来有点棘手。我想要做的是找到一种方法来重新考虑这一点,这样我的代码就不那么笨重,也不会占用太多空间。
我曾考虑将if语句的集合更改为switch语句,但我发现switch语句不能像上面那样处理两个参数。如果有任何其他方式我可以重新考虑我的代码,但保持相同的功能或我坚持我的if语句集合?
修改的
更新为包含我的7个语句中的两个。 请注意,我正在尝试减少我拥有的IF语句的数量,或者找到一种更聪明的方法来实现它们。我不想添加任何额外的代码行或if语句。
答案 0 :(得分:2)
老实说,我认为在你的情况下最可读和可维护的只是将那些if块中的逻辑移动到函数中:
if(hit.collider.gameObject.tag == "Colour1" && start_time > look_at_time)
{
DoTheThing(new_colour1);
}
if(hit.collider.gameObject.tag == "Colour2" && start_time > look_at_time)
{
DoTheThing(new_colour2);
}
//and so on
void DoTheThing(MyType newColour)
{
newColour.ChangeObjectMaterialColour(hit.collider.gameObject.renderer.material.color);
var colums = GameObject.FindGameObjectsWithTag("column");
foreach( GameObject c in colums)
c.GetComponent<MeshRenderer>().materials[1].color = newColour.orignalMaterial;
}
关于使用switch
,您当然可以这样做:
switch(hit.collider.gameObject.tag)
{
case "Colour1":
if (start_time>look_at_time)
{
//do something
}
else if (start_time<look_at_time)
{
//something else
}
else
{
//they are equal, etc, etc
}
break;
case "Colour2":
//and so on
}
或者如果所有if块在start_time
和look_at_time
之间进行相同的比较,那么您可以将其反转:
enum TimeDifference
{
LessThan,Equal,GreaterThan
}
//just one way to get a constant switchable value, not necessarily the best
var diff = TimeDifference.Equal;
if (start_time>look_at_time) {diff=TimeDifference.LessThan}
else if (start_time<look_at_time) {diff=TimeDifference.GreaterThan}
switch(diff)
{
case TimeDifference.LessThan:
switch(hit.collider.gameObject.tag)
{
case "Colour1":
//do something for Colour1
break;
case "Colour2":
//do something for Colour2
break;
}//end switch Colour
break;
case TimeDifference.GreaterThan
switch(hit.collider.gameObject.tag)
{
case "Colour1":
//do something for Colour1
break;
case "Colour2":
//do something for Colour2
break;
}//end switch Colour
break;
default:
//nested switch for Colour in the == case, you get the idea.
}
尽管上述任何一个与几个格式良好且分离的if
块的可读性是非常值得商榷的。
另一种方法是使用Dictionary<string,Action<int,int>>
:(假设start_time
和look_at_time
都是int
并且所有逻辑都以某种方式涉及它们。
var Actions = new Dictionary<string,Action<int,int>>();
Actions.Add("Colour1",(s,l)=>{
if (start_time>look_at_time)
{
//do something
}
else if (start_time<look_at_time)
{
//something else
}
else
{
//they are equal, etc, etc
}
});
然后您的主代码变为1行:
Actions[hit.collider.gameObject.tag](start_time,look_at_time);
我相信还有很多方法可以重新安排代码。
答案 1 :(得分:1)
感谢您更新代码,现在我们可以开始查看重复的内容了。例如,两个代码块之间的唯一区别是if语句中的字符串"Color1"
和"Color2"
,以及new_colour1
替换的变量new_colour2
。 / p>
从这里我建议如下:
//This should be declared once - e.g. class level not method level.
var colorDict = new Dictionary<string, [new_color_type]>
{{"Colour1", new_colour1}, {"Colour2", new_colour2}};
[new_color_type] newColor;
if(start_time > look_at_time && colorDict.TryGetValue(
hit.collider.gameObject.tag,
out newColor))
{
newColor.ChangeObjectMaterialColour(
hit.collider.gameObject.renderer.material.color);
var colums = GameObject.FindGameObjectsWithTag("column");
foreach( GameObject c in colums)
c.GetComponent<MeshRenderer>().materials[1].color =
newColor.orignalMaterial;
}