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

时间:2013-09-23 22:23:12

标签: c# null resharper conditional

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

1 个答案:

答案 0 :(得分:4)

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

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

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

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