static void Main(string[] args)
{
DataSet ds = null;
if (false && ds.Tables[0].Rows.Count > 0)
{
Console.WriteLine("Fuck");
}
else
{
Console.WriteLine("Shit");
}
if (true && ds.Tables[0].Rows.Count > 0)
{
Console.WriteLine("WOW");
}
else
{
Console.WriteLine("KAO");
}
Console.ReadKey();
}
這段代碼乍看沒問題,并且在運(yùn)行時也給出了我們期望的結(jié)果,即第一段語句
private static void Main(string[] args)
{
DataSet ds = null;
Console.WriteLine("Shit");
if (ds.Tables[0].Rows.Count > 0)
{
Console.WriteLine("WOW");
}
else
{
Console.WriteLine("KAO");
}
Console.ReadKey();
}
其實(shí),如果你仔細(xì)觀察,在輸入這段代碼的過程中,VS就已經(jīng)提示if (false && ds.Tables[0].Rows.Count > 0)中,后者是不可達(dá)的。這是即時編譯的效果。既然即時編譯說后面的代碼不可達(dá),就意味著不可達(dá)的代碼會在編譯期被切掉。因此,剛才我們在上面看到的編譯結(jié)果也就是自然的事情了。
同樣,如果你直接把1 == 0, 1 == 1這樣的條件拼上去的話,編譯器也會發(fā)現(xiàn)的。所以我們要找一種不會被編譯器發(fā)現(xiàn)的寫法,要讓我們的條件判定代碼只能在運(yùn)行時執(zhí)行,而不是編譯時被調(diào)整。比如下面這種:
代碼如下:
static void Main(string[] args)
{
DataSet ds = null;
int i = 0;
int j = 1;
if (i + j == 0 && ds.Tables[0].Rows.Count > 0)
{
Console.WriteLine("Fuck");
}
else
{
Console.WriteLine("Shit");
}
if (i + j == 1 && ds.Tables[0].Rows.Count > 0)
{
Console.WriteLine("WOW");
}
else
{
Console.WriteLine("KAO");
}
Console.ReadKey();
}
我們再來執(zhí)行,發(fā)現(xiàn)這次的結(jié)果是真正意義的滿足了我們的目的,說明了當(dāng)多個條件進(jìn)行邏輯與的時候,C#的執(zhí)行機(jī)制:
寫這篇文章的意義,是為了讓大家在寫程序的時候,注意條件中可能發(fā)生異常的地方。比如我們模擬String.IsNullOrEmpty()。
在or關(guān)系中,只要有一個true,整個表達(dá)式就是true了。但如果你讓可能引發(fā)異常的語句先于之后會返回true的語句執(zhí)行,就會爆。
比如這樣寫的話會爆,因?yàn)榕袛郘ength的前提是得有個string:
代碼如下:
public static bool IsNullOrEmpty(string str)
{
if (str.Length == 0 || str == null)
{
return true;
}
return false;
}
這樣寫就正常:
![]()
代碼如下:
public static bool IsNullOrEmpty(string str)
{
if (str == null || str.Length == 0)
{
return true;
}
return false;
}
微軟是這樣寫的,碉堡了!
代碼如下:
public static bool IsNullOrEmpty(string value)
{
if (value != null)
{
return (value.Length == 0);
}
return true;
}
上面這段代碼可以用reflector打開mscorlib中的System.String找到~聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com