为什么 R# 用这段代码说“表达式总是假的”

本文关键字:表达式 段代码 代码 为什么 | 更新日期: 2023-09-27 18:32:26

Resharper在下面的InitializeObjects()中标记了两个"代码中的冗余":

public string InitializeObjects()
{
    string RetVal = null; // <-- Value assigned is not used in any execution path
    try
    {
        dbConnection = new System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;User ID=PlatypusBO;Password=PlatypusBO;Data Source="
            + Database + ";Persist Security Info=False;Jet OLEDB:System database=" + Workgroup);
        dbConnection.Open();
        RetVal = FastLookup(ref dbConnection, "setting_value", "t_settings", "key_setting='TableVersion'").ToString();
        if((RetVal == "") || (RetVal == null)) // <- Resharper says, "Expression is always false"
            RetVal = "0.0.0.0";
    }
    catch(Exception)
    {
        RetVal = null;
    }
    return RetVal;
}
private object FastLookup(ref System.Data.OleDb.OleDbConnection tConn, string fldName, string tName, string strFilter)
{
    if (tConn == null) 
    {
        return "";
    }
    object RetVal = "";
    string sqlCriteria = "";
    if (strFilter != "") 
    {
        sqlCriteria = " WHERE " + strFilter;
    }
    if (tConn.State != System.Data.ConnectionState.Open) 
    {
        tConn.Open();
    }
    System.Data.OleDb.OleDbCommand catCMD = tConn.CreateCommand();
    catCMD.CommandText = "SELECT " + fldName + " FROM " + tName + sqlCriteria;
    try 
    {
        using (System.Data.OleDb.OleDbDataReader myReader = catCMD.ExecuteReader())
        {
            if (myReader != null && myReader.Read())
            {
                RetVal = myReader.IsDBNull(0) ? "" : myReader.GetValue(0);
            }
            else
            {
                RetVal = "";
            }
        }
        //myReader.Close();
    } 
    catch (Exception) 
    {
        RetVal = "";
    } 
    finally 
    {
        catCMD.Dispose();
    }
    return RetVal;
}

。我不知道为什么;似乎第一个"分配的值未在任何执行路径中使用"是不正确的,因为有一个后续测试来查看 RetVal 是否为空。

第二个("表达式总是假的")对我来说也没有意义,因为 RetVal 可以是这些 val 中的任何一个(空字符串或 null),因为它在代码中的点都被分配了。

我 (99.9999%) 确定 R# 是正确的,但为什么它是对的?

更新

将其更改为此枪口 R#:

public string InitializeObjects()
{
    string RetVal;
    try
    {
        dbConnection = new System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;User ID=DuckbilledPBO;Password=DuckbilledPBO;Data Source="
            + Database + ";Persist Security Info=False;Jet OLEDB:System database=" + Workgroup);
        dbConnection.Open();
        RetVal = FastLookup(ref dbConnection, "setting_value", "t_settings", "key_setting='TableVersion'");
        if (string.IsNullOrEmpty(RetVal))
            RetVal = "0.0.0.0";
    }
    catch(Exception)
    {
        RetVal = null;
    }
    return RetVal;
}
private string FastLookup(ref System.Data.OleDb.OleDbConnection tConn, string fldName, string tName, string strFilter)
{
    if (tConn == null) 
    {
        return "";
    }
    string RetVal;
    string sqlCriteria = "";
    if (strFilter != "") 
    {
        sqlCriteria = " WHERE " + strFilter;
    }
    if (tConn.State != System.Data.ConnectionState.Open) 
    {
        tConn.Open();
    }
    System.Data.OleDb.OleDbCommand catCMD = tConn.CreateCommand();
    catCMD.CommandText = "SELECT " + fldName + " FROM " + tName + sqlCriteria;
    try 
    {
        using (System.Data.OleDb.OleDbDataReader myReader = catCMD.ExecuteReader())
        {
            if (myReader != null && myReader.Read())
            {
                RetVal = myReader.IsDBNull(0) ? "" : myReader.GetValue(0).ToString();
            }
            else
            {
                RetVal = "";
            }
        }
    } 
    catch (Exception) 
    {
        RetVal = "";
    } 
    finally 
    {
        catCMD.Dispose();
    }
    return RetVal;
}

为什么 R# 用这段代码说“表达式总是假的”

正如注释中提到的,方法的返回类型是问题所在,通过使用对象作为返回类型并将其与空字符串进行比较,您正在进行引用比较。

为了说明这一点,这里有一个简单的例子,Resharper会告诉你完全相同的事情。

object oneString = " ";
string newString=new string(' ',1);
if (newString == oneString)
{
    //doesn't happen
}

一种解决方案是将返回类型更改为字符串或将返回的对象强制转换为字符串。