简体   繁体   English

错误:并非所有代码路径都返回值?

[英]error: Not All Code Paths Return A value?

I am Getting this Error (Not All Code Paths Return A Value). 我收到此错误(并非所有代码路径返回值)。 I want to insert data in my database with unique key constraint. 我想用唯一键约束在我的数据库中插入数据。 but when i added this in my code my method is giving me this error. 但是当我在我的代码中添加它时,我的方法给了我这个错误。

Here is my code 这是我的代码

  public string Insert()
    {

        SqlConnection Conn = new SqlConnection(@"Data Source=ZARAK\SQLEXPRESS;Initial Catalog=ProjectDAL;integrated security=true");


        try
        {
            Conn.Open();
            SqlCommand cmd = new SqlCommand("Insert INTO tbl_User(Name,Email,Password) VALUES ('" + name + "','" + email + "','" + password + "')", Conn);


            int restl = cmd.ExecuteNonQuery();
            //temp = true;
            return "Record Inserted successfully!";
        }
        catch (SqlException ex)
        {
            if (ex.Number == 2627)
            {
                 return "Record Already Exists";
            }
        }
        finally
        {
            Conn.Close();
        }
    }

Your problem is here: 你的问题在这里:

catch (SqlException ex)
{
    if (ex.Number == 2627)
    {
        return "Record Already Exists";
    }
    // **
}

If you look at the code paths of your application, each if also implicitly adds an else . 如果你看看你的应用程序的代码路径,每个if也隐含增加了一个else In this case the else doesn't contain a return statement, hence the error. 在这种情况下, else不包含return语句,因此错误。

And then there's exceptions... 然后是例外......

Exceptions are there to handle exceptional cases. 处理特殊情况的例外情况。 There's this implicit agreement amongst software developers that catch implies handle it appropriately . 软件开发人员之间存在这种隐含的协议, catch意味着适当地处理它

One way to handle it is to inform the user that the record already exists (I'm guessing that's what you do). 处理它的一种方法是通知用户记录已经存在(我猜这是你做的)。 If another thing happens, it's not always productive to inform the user of the error; 如果发生了其他事情,通知用户错误并不总是有效的; you might simply want to try again in a few seconds (deadlock) or do something else. 你可能只想在几秒钟内再次尝试(死锁)或做其他事情。 Usually you handle code like that on a higher level, and let the exception ripple. 通常你会在更高级别上处理类似的代码,并让异常涟漪。

As a result, I cannot tell you what the code of ** needs to be; 结果,我不能告诉你**的代码需要什么; you need to decide that for yourself based on what you want to achieve. 你需要根据你想要达到的目标自己决定。

For example: 例如:

catch (SqlException ex)
{
    if (ex.Number == 2627)
    {
        return "Record Already Exists"; // user needs to do something
    }

    // We don't want to handle the rest here:
    throw;
}

In your code The possible code paths are 在您的代码中可能的代码路径是

  1. =>Try=>finally=> Exit
  2. =>catch=>ex.Number == 2627=>finally=>Exit
  3. =>catch=>ex.Number != 2627=>finally=>Exit

Through your code you have handled the first two; 通过你的代码你已经处理了前两个; The compiler will not know what to do if he met with the third Condition that's why it showing such error. 如果遇到第三个条件,编译器将不知道该怎么做,这就是它出现这种错误的原因。 This can be solved by treating the third code path( ex.Number != 2627 ). 这可以通过处理第三个代码路径来解决( ex.Number != 2627 )。 Now consider the following code: 现在考虑以下代码:

catch (SqlException ex)
{
    if (ex.Number == 2627)
    {
        return "Record Already Exists";
    }
    return "Some other error occurred";
}

One more thing you have to notice is the Plain Text queries. 您需要注意的另一件事是纯文本查询。 Which will opens a wide door for SQL Injection. 这将为SQL Injection打开一扇大门。 So i request you to use parameterized queries . 所以我请求你使用参数化查询

Including all these changes, the Method signature for the Insert() will be like the following: 包括所有这些更改, Insert()的Method签名将如下所示:

public string Insert()
{
    // Assuming Name email and passwords are global variables
    // Or else need to get them
    string conStr = @"Data Source=ZARAK\SQLEXPRESS;Initial Catalog=ProjectDAL;integrated security=true";
    int queryResult = 0;
    try
    {
        string querySQL = "Insert INTO tbl_User(Name,Email,Password)VALUES(@name,@email,@password)";
        using (SqlConnection Conn = new SqlConnection(conStr))
        {
            using (SqlCommand cmd = new SqlCommand(querySQL, Conn))
            {
                cmd.Parameters.Add("@name", SqlDbType.VarChar).Value = Name;
                cmd.Parameters.Add("@email", SqlDbType.VarChar).Value = email;
                cmd.Parameters.Add("@password", SqlDbType.VarChar).Value = password;
               queryResult= cmd.ExecuteNonQuery();
            }
        }
        return queryResult + "Record/s Inserted successfully!";
    }
    catch (SqlException ex)
    {
        if (ex.Number == 2627)
        {
            return "Record Already Exists";
        }
        return "Some other error";
    }           
}

Alter your code into this to make sure that you have a return value. 将代码更改为此以确保您具有返回值。

public string Insert()
{
    var result = String.Empty;
    SqlConnection Conn = new SqlConnection(@"Data Source=ZARAK\SQLEXPRESS;Initial Catalog=ProjectDAL;integrated security=true");


    try
    {
        Conn.Open();
        SqlCommand cmd = new SqlCommand("Insert INTO tbl_User(Name,Email,Password) VALUES ('" + name + "','" + email + "','" + password + "')", Conn);


        int restl = cmd.ExecuteNonQuery();
        //temp = true;
        result =  "Record Inserted successfully!";
    }
    catch (SqlException ex)
    {
        if (ex.Number == 2627)
        {
             result = "Record Already Exists";
        }
        else {
            result = ex.Message; // For other exceptions
        }
    }
    finally
    {
        Conn.Close();
    }

    return result;
}

As the error states, you must return a string in all execution paths. 如错误所述,您必须在所有执行路径中返回一个字符串。

public string SomeMethod()
{
    try
    {
        //Path 1
        return "Path 1";
    }
    catch (SqlException ex)
    {
        if (...) {
             //Path 2
             return "Path 2";              
        }

       //Path 3
       //Return or rethrow.
       //return "Path 3";
       throw;
    }
    finally
    {
        //Clean Up Resources
    }
}

If your application throw an Exception and the Exception number is not equals to 2627, your method will not return a string value. 如果您的应用程序抛出异常并且异常编号不等于2627,则您的方法将不返回字符串值。

        try
        {
            Conn.Open();
            SqlCommand cmd = new SqlCommand("Insert INTO tbl_User(Name,Email,Password) VALUES ('" + name + "','" + email + "','" + password + "')", Conn);


            int restl = cmd.ExecuteNonQuery();
            //temp = true;
            return "Record Inserted successfully!";
        }
        catch (SqlException ex)
        {
            if (ex.Number == 2627)
            {
                return "Record Already Exists";
            }
            return "Your Text";
        }
        finally
        {
            Conn.Close();
        }
        return "Your Text";
    }

In additional to atlaste 's nice answer. 除了atlaste的好答案。 In case of C# 6.0 in order to avoid such errors and simplify try .. catch block you can put exception filter : C#6.0的情况下,为了避免这样的错误并简化try .. catch块你可以放置异常过滤器

  try {
    ...
  }
  catch (SqlException ex) when (ex.Number == 2627) {
    return "Record Already Exists";
  }

no if , no throw; 不, if ,没有throw;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM