关于C# if语句中并列条件的执行

所属分类: 网络编程 / ASP.NET 阅读数: 743
收藏 0 赞 0 分享
C#语言中也是如此。当多个条件进行逻辑与操作的时候,判定会从表达式左边执行到右边,遇到任何一个为假,后面就都不做了。这很聪明,然而如果后面的条件会抛出异常,就是个潜在的问题。一旦之前的条件为真,就会继续执行,执行到抛出异常的条件时,程序就爆了,哈哈。
我们可以写个简单的demo试试。下面的这段代码是坑爹的,之后我会说明原因,但大家可以先从直观的层面上理解一下,最后我会给出正确的测试方法。
复制代码 代码如下:

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();
}

这段代码乍看没问题,并且在运行时也给出了我们期望的结果,即第一段语句输出Shit,不抛出异常(当前面为false,后面会抛异常的ds.Tables[0].Rows.Count > 0就不做),而第二段语句因为之前是true,所以要执行对dataset的判断,所以抛出异常。但如果用reflector反编译程序集,就会发现,编译器已经把上面的代码优化成了下面这种形式,我们的if语句中写死的true和false已经被阉割掉了,所以并不能说明if语句执行的问题。
复制代码 代码如下:

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();
}

其实,如果你仔细观察,在输入这段代码的过程中,VS就已经提示if (false && ds.Tables[0].Rows.Count > 0)中,后者是不可达的。这是即时编译的效果。既然即时编译说后面的代码不可达,就意味着不可达的代码会在编译期被切掉。因此,刚才我们在上面看到的编译结果也就是自然的事情了。
同样,如果你直接把1 == 0, 1 == 1这样的条件拼上去的话,编译器也会发现的。所以我们要找一种不会被编译器发现的写法,要让我们的条件判定代码只能在运行时执行,而不是编译时被调整。比如下面这种:
复制代码 代码如下:

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();
}

我们再来执行,发现这次的结果是真正意义的满足了我们的目的,说明了当多个条件进行逻辑与的时候,C#的执行机制:

写这篇文章的意义,是为了让大家在写程序的时候,注意条件中可能发生异常的地方。比如我们模拟String.IsNullOrEmpty()。
在or关系中,只要有一个true,整个表达式就是true了。但如果你让可能引发异常的语句先于之后会返回true的语句执行,就会爆。
比如这样写的话会爆,因为判断Length的前提是得有个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找到~
更多精彩内容其他人还在看

asp.net网站首页根据IP自动跳转指定页面的示例

本文介绍的程序主要实现根据IP地址或地址段或IP所在城市进行自动跳转到指定页面的功能,需要的朋友可以参考下
收藏 0 赞 0 分享

asp.net无法获取iis目录的问题解决方法

本文介绍了Asp.Net无法获取IIS拾取目录的解决办法,需要的朋友可以参考下
收藏 0 赞 0 分享

.net中 发送邮件内容嵌入图片的具体实例

这篇文章主要介绍了.net中 发送邮件内容嵌入图片的具体实例,需要的朋友可以参考下
收藏 0 赞 0 分享

在.net中用CheckBoxList实现单选

用CheckBoxList实现单选的原因是我觉得CheckBoxList控件页面展示效果要好看一些,需要的朋友可以参考下
收藏 0 赞 0 分享

ASP.NET―001:GridView绑定List、页面返回值具体实现

这篇文章主要介绍了ASP.NET―GridView绑定List、页面返回值具体实现,需要的朋友可以参考下
收藏 0 赞 0 分享

Ajax实现异步刷新验证用户名是否已存在的具体方法

由于要做一个注册页面,看到许多网站上都是使用Ajax异步刷新验证用户名是否可用的,所以自己也动手做一个小实例
收藏 0 赞 0 分享

ASP.NET汉字转拼音 - 输入汉字获取其拼音的具体实现

这篇文章主要介绍了ASP.NET汉字转拼音 - 输入汉字获取其拼音的具体实现,需要的朋友可以参考下
收藏 0 赞 0 分享

.Net消息队列的使用方法

这篇文章主要介绍了.Net消息队列的使用方法,需要的朋友可以参考下
收藏 0 赞 0 分享

C# web api返回类型设置为json的两种方法

web api写api接口时默认返回的是把你的对象序列化后以XML形式返回,那么怎样才能让其返回为json呢,下面为大家介绍几种不错的方法
收藏 0 赞 0 分享

asp.net获取网站目录物理路径示例

这篇文章主要介绍了asp.net获取网站目录物理路径的方法,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多