使用foreach循环时使用未分配的局部变量

时间:2017-02-10 04:28:17

标签: c# unassigned-variable

我有一个代码块,可以从存储过程中获取一些数据。收到数据后,我想将值分配给" isExisting"视情况而定。我不想为" isExisting"分配值。在宣布时。

bool isExisting;
using (var conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ToString()))
{
    conn.Open();
    using (SqlCommand cmd = new SqlCommand("some_stored_procedure", conn))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add(new SqlParameter("input", value));
        using (var adapter = new SqlDataAdapter(cmd))
        {
            DataSet ds = new DataSet();
            adapter.Fill(ds);
            if (ds.Tables.Count > 0)
            {
                if (ds.Tables[0].Rows.Count == 0)
                    isExisting = false;
                else
                {
                    foreach (DataRow row in ds.Tables[0].Rows)
                    {
                        if (row["Key"].ToString() == ValueToCompareWith)
                        {
                            isExisting = true;
                            break;
                        }
                        else
                            isExisting = false;
                    }
                }

            }
            else
                isExisting = false;
        }
    }
}
if (!isExisting) //Step :getting error "use of unassigned local variable"
{
}

我想我已经涵盖了所有条件和变量" isExisting"当它到达" Step"时会有一个值,但我仍然遇到编译器错误。

问题已经开始,因为我的代码审核工具正在发表评论

"当为本地变量分配了一个未被任何后续指令读取的值时,就会发生死存储。计算或检索一个值只是为了覆盖它或丢弃它,可能表明代码中存在严重错误。即使它不是错误,它充其量也是浪费资源。因此,应使用所有计算值。"
不合规的代码示例

void CalculateRate(int a, int b)
{
  int i;

  i = a + b; // Noncompliant; calculation result not used before value is overwritten
  i = DoSomething();  // Noncompliant; retrieved value not used
  for (i = 0; i < 10; i++)
  {
    //  ...
  }
  // ...
}

4 个答案:

答案 0 :(得分:1)

编译器是一个简单的东西。它不会检查所有逻辑以确保变量始终获得值。那不是它的工作。只需给isExisting一个默认值以保持编译器满意,然后您的实际代码将设置正确的值(正如您已经说过的那样)。

答案 1 :(得分:1)

编译器无法确定每一段代码是否会被命中 - 例如,如果此循环中没有行:

foreach (DataRow row in ds.Tables[0].Rows)

所以因此不会命中整个if块。

设置默认值。

答案 2 :(得分:1)

正如其他人所指出的,编译器不够智能,无法知道您是否实际为变量赋值。

您可以使用一些Linq:

来解决这种歧义,并大量清理您的代码
bool isExisting;
using (var conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ToString()))
{
    conn.Open();
    using (SqlCommand cmd = new SqlCommand("some_stored_procedure", conn))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add(new SqlParameter("input", value));
        using (var adapter = new SqlDataAdapter(cmd))
        {
            DataSet ds = new DataSet();
            adapter.Fill(ds);

            isExisting = ds.Tables
                .OfType<DataTable>()
                .Take(1)
                .SelectMany(t => t.Rows.OfType<DataRow>())
                .Any(r => r["Key"].ToString() == ValueToCompareWith);
        }
    }
}
if (!isExisting)
{
}

另一种方法是将isExisting检查分解为单独的方法:

bool CheckIsExisting(object value, string valueToCompareWith) 
{
    using (var conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ToString()))
    {
        conn.Open();
        using (SqlCommand cmd = new SqlCommand("some_stored_procedure", conn))
       {
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add(new SqlParameter("input", value));
            using (var adapter = new SqlDataAdapter(cmd))
            {
                DataSet ds = new DataSet();
                adapter.Fill(ds);
                if (ds.Tables.Count != 0 && ds.Tables[0].Rows.Count != 0)
                {
                    foreach (DataRow row in ds.Tables[0].Rows)
                    {
                        if (row["Key"].ToString() == ValueToCompareWith)
                        {
                            return true;
                        }
                    }
               }
           }
       }
    }

    return false;
}

然后做:

if (!CheckIsExisting(value, ValueToCompareWith))
{
    // do something...
}         

答案 3 :(得分:0)

Bool

默认值 false 。请在您的代码中提供。

bool isExisting=false;

您在代码中编写的整个业务逻辑应该注意

if (!isExisting) {
}

背后的主要逻辑是编译器几乎不会打扰你编写的脚本。它只是在任何条件下使用之前只需要指定的值。

请参阅here了解详情。