iT邦幫忙

1

C# 優化使用過多的IF Else代碼

c#
Ks 2018-12-19 17:08:344152 瀏覽
  • 分享至 

  • xImage

請問有辦法優化和簡化以下程式碼嗎?

  1. 檢查字串B和C是否符合規格,不符合顯示錯誤訊息
  2. 檢查A是否存在資料庫,不存在顯示錯誤訊息
  3. 檢查字串B和C是否存在資料庫,不存在顯示錯誤訊息

true代表檢查錯誤,false代表檢查正確,
所以第一行!A代表檢查A是否為數字,如果判斷錯誤就return true,是數字return false
B和C同樣

check_A-> true or false 判斷是否為數字
check_B-> true or false 判斷字串是否符合B規格
check_C-> true or false 判斷字串是否符合C規格

if(!check_A)
  var result = functionA.get(value)
  if(result == null)
     string msg = “sorry, can’t get A.”;
     return RedirectToAction(“error”,msg);
   else
     return RedirectToAction(“index”,result);
else
   if(check_B and check_C)
     string msg = “Sorry,B and C failed.”;
     return RedirectToAction(“error”,msg);
   else
     if(!check_B)
         result = functionB.get(value)
         if(result == null)
           string msg = “Sorry,can’t get B.”;
           return RedirectToAction(“error”,msg);
         else
           return RedirectToAction(“index”,result);
      else
         result = functionC.get(value)
         if(result == null)
           string msg = “Sorry,can’t get C.”;
           return RedirectToAction(“error”,msg);
         else
           return RedirectToAction(“index”,result);
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
5
小碼農米爾
iT邦高手 1 級 ‧ 2018-12-19 22:25:09
最佳解答

我修改了一些地方,主要是提高程式可讀性。

建議如下:

  1. 避免反邏輯,例如 true代表檢查錯誤
  2. 避免 if else 多層嵌套
  3. 錯誤訊息的部分使用 Exceptiontry catch 統一處理
try
{
    //A是數字
    if (isNumber(A))
    {
        var result = functionA.get(value);
        if (result == null)
        {
            throw new Exception("sorry, can’t get A.");
        }
        return RedirectToAction("index", result);
    }
    //B 和 C 都不合規格
    if (!isMatch(B) && !isMatch(C))
    {
        throw new Exception("Sorry,B and C failed.");
    }
    //B 符合規格
    if (isMatch(B))
    {
        var result = functionB.get(value);
        if (result == null)
        {
            throw new Exception("Sorry,can’t get B.");
        }
        return RedirectToAction("index", result);
    }
    //C 符合規格
    if (isMatch(C))
    {
        var result = functionC.get(value);
        if (result == null)
        {
            throw new Exception("Sorry,can’t get C.");
        }
        return RedirectToAction("index", result);
    }
}
catch(Exception ex)
{
    return RedirectToAction("error", ex.Message);
}
看更多先前的回應...收起先前的回應...

樓主的同名異式用得很厲害...

檢查字串B和C是否符合規格--->B,C是「字串」
字串是否符合B,C規格--->B,C是「某種規格」
B= true or false 判斷字串是否符合B規格--->判斷是否符合規格的Boolean值

我手中的牌太弱了
我決定蓋牌
放棄這一回合

翻開覆蓋的魔法卡

Ks iT邦新手 3 級 ‧ 2018-12-20 16:08:14 檢舉

感谢,抱歉,说明有些混乱,目前有修改掉反逻辑的写法了

ant1017 iT邦新手 2 級 ‧ 2018-12-21 09:38:25 檢舉

程式可讀性真的很重要,至少可以做點功德,造福銜接的人

Luke iT邦研究生 5 級 ‧ 2018-12-21 16:38:17 檢舉
try
{
    //A是數字
    if (isNumber(A))
    {
        var result = functionA.get(value);
        if (result == null)
        {
            throw new Exception("sorry, can’t get A.");
        }
    }
    //B 和 C 都不合規格
    if (!isMatch(B) && !isMatch(C))
    {
        throw new Exception("Sorry,B and C failed.");
    }
    //B 符合規格
    if (isMatch(B))
    {
        var result = functionB.get(value);
        if (result == null)
        {
            throw new Exception("Sorry,can’t get B.");
        }
    }
    //C 符合規格
    if (isMatch(C))
    {
        var result = functionC.get(value);
        if (result == null)
        {
            throw new Exception("Sorry,can’t get C.");
        }
    }
    
    return RedirectToAction("index", result);
}
catch(Exception ex)
{
    return RedirectToAction("error", ex.Message);
}

return RedirectToAction("index", result);

應該放最後,有錯都出去了

不然就是永遠都在A符合,就進去
A符合,B、C不符合也可以進去
不過要看您的需求是甚麼?
只要一個A、B、C條件,符合進去,還是三個都符合才進去

3
來杯拿鐵
iT邦新手 2 級 ‧ 2018-12-19 19:56:55

之前跟你有同樣問題
後來發現可以打包程式
只要打包程式就可以減少2/3行

fun(result,temp){
if(result == null)
           string msg = “Sorry,can’t get “+temp+ “. “;
           return RedirectToAction(“error”,msg);
         else
           return RedirectToAction(“index”,result);
}

然後遇到跟這個程式有關
fun(functionC.get(value),c);
一行就能解決

應該每個語言都有類似功能
你可以找看看說明

Ks iT邦新手 3 級 ‧ 2018-12-20 16:09:03 檢舉

感谢,这方法似乎可以减少部分程式码,会参考看看

3
石頭
iT邦高手 1 級 ‧ 2018-12-20 16:19:48

這是一個很適合使用OOP 和Template method Pattern的案例.

製作一個hock method protected abstract string GetValidResult([ValueType] value); 給子類作擴充,驗證邏輯在子類別實現.

public abstract class CheckBase{
	
	protected abstract string ErrorMessage { get; }
	
  	protected abstract string GetValidResult([ValueType] value);
	
	public RedirectToRouteResult GetResult([ValueType] value){
		
		var result = IsValid(value);
		
		if(result == null)
		    return RedirectToAction(“error”,ErrorMessage); 
		
	    return RedirectToAction(“index”,result);
	}
}

public class CheckA : CheckBase{
	protected override string FunctionName { 
		get{
			return "sorry, can’t get A.";	
		}
	}
	
	protected override string GetValidResult ([ValueType] value){
		return functionA.get(value);	
	}
}

public class FailWithBC : CheckBase{
	protected override string FunctionName { 
		get{
			return "Sorry,B and C failed.";	
		}
	}
	
	protected override string GetValidResult ([ValueType] value){
		return false;	
	}
}

public class CheckB : CheckBase{
	protected override string FunctionName { 
		get{
			return "Sorry,can’t get B.";	
		}
	}
	
	protected override string GetValidResult ([ValueType] value){
		return functionB.get(value);	
	}
}

public class CheckB : CheckBase{
	protected override string FunctionName { 
		get{
			return "Sorry,can’t get C.";	
		}
	}
	
	protected override string GetValidResult ([ValueType] value){
		return functionC.get(value);	
	}
}

使用時只需倚賴抽象,呼叫 GetResult 方法

CheckBase action = null;

if(!check_A)
	action = new CheckA();
else {
	if(check_B && check_C)
		action = new FailWithBC(); 
	else if(!check_B)
		action = new CheckB(); 
	else
		action = new CheckC(); 
}

return action.GetResult(value);

NOTE

[ValueType] 可替換成你value物件的類型

我要發表回答

立即登入回答