【问题标题】:Passing a method as an argument in another method [duplicate]将方法作为参数传递给另一个方法[重复]
【发布时间】:2013-07-01 06:21:54
【问题描述】:

我想传递一个方法作为参数来从我的程序中删除重复的代码。这是我想要的功能:

 private void sqlQuery(Method sqlMethod)
{
    conn.ConnectionString = ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString;
    try
    {
        //open SQL connection
        conn.Open();
        sqlMethod();
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.Write(ex.ToString());
    }
    finally
    {
        conn.Close();
    }
}

使用:

private void insertTemplate()
{
    //create SQL command
    SqlCommand insertTemplate = new SqlCommand("INSERT INTO [SavedDescriptionTemplates] (SavedDescription, UserId, CreatedDate) VALUES (@descriptionParam, @userIdParam, @createdDateParam)", conn);
    //create and assign parameters
    insertTemplate.Parameters.AddWithValue("@descriptionParam", descriptionInput.Text);
    insertTemplate.Parameters.AddWithValue("@userIdParam", Int32.Parse(userNameDropDown.SelectedItem.Value));
    insertTemplate.Parameters.AddWithValue("@createdDateParam", DateTime.Now);
    //execute command and retrieve primary key from the above insert and assign to variable
    insertTemplate.ExecuteNonQuery();
}

电话是:

sqlQuery(insertTemplate());

这可能吗?

【问题讨论】:

  • 除了重复的问题,我们还有Action可用
  • 请考虑将您的数据库代码包装在 using 块中,例如 using (SqlConnection connection = new SqlConnection(connectionString)){...}
  • 请注意,您最好将连接对象定义为sqlQuery 的局部变量并将其作为参数传递给您的委托,而不是使其成为实例字段并让其他方法引用他们不知道是否打开的连接。然后你会想要使用Action<SqlConnection> 委托,而不是Action,并让insertTemplate 接受连接作为参数。这可确保您知道连接在任何地方都可以访问,它是打开的。也可以结合DOK的评论。

标签: c#


【解决方案1】:

使用Action 委托。

改变

private void sqlQuery(Method sqlMethod)

进入

private void sqlQuery(Action sqlMethod)

sqlQuery(insertTemplate());

进入

sqlQuery(insertTemplate);

【讨论】:

    【解决方案2】:

    您可以通过委托来实现。

    例如使用Action:

    private void sqlQuery(Action action)
    {
        conn.ConnectionString = ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString;
        try
        {
            //open SQL connection
            conn.Open();
    
            action();
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.Write(ex.ToString());
        }
        finally
        {
            conn.Close();
        }
    }
    

    【讨论】:

      【解决方案3】:

      是的,但略有不同...

      试试这个:

      sqlQuery(insertTemplate); // don't CALL the method, just name it
      

      并像这样声明 sqlQuery:

      private void sqlQuery(Action sqlMethod)
      

      【讨论】:

        【解决方案4】:

        查看delegates。在您的情况下,由于您的方法不带参数,您可以使用内置的 Action 委托:

        private void sqlQuery(Action sqlMethod)
        {
            //...
        }
        
        sqlQuery(insertTemplate);
        

        【讨论】:

          【解决方案5】:

          C# 中的逻辑块作为delegates 传递。有多种声明委托的方法 - 您可以定义自定义委托,或使用预定义类型之一:

          • 您可以将Action<...> 用于不返回值的委托,或者
          • 您可以将Func<...,R> 用于返回值的委托。

          下面是定义接受委托的函数的一种方法:

          private void sqlQuery(Action<IDbConnection> sqlMethod) {
             ...
             sqlMethod(conn);
             ...
          }
          

          使用命名或匿名委托调用sqlQuery,该委托可以内联、命名方法或 lambda 表达式定义:

          // Using some method that takes IDbConnection
          sqlQuery(MySqlMethod);
          // Using an anonymous delegate
          sqlQuery((conn) => {
              ... // Do something with conn
          });
          

          【讨论】:

            【解决方案6】:

            是的。您需要使用委托、匿名函数或 lambda 表达式。

            这是一个简单的例子:

            public void SomeMethod(Action<string> passedMethod)
            {
                passedMethod("some string");
            }
            
            public void Caller()
            {
                SomeMethod(x => Console.WriteLine(x));
            }
            

            如果你运行“Caller”,它会输出“some string”。

            【讨论】:

              【解决方案7】:

              代表就是答案 -> Microsoft on C# Delegates

              public void delegate MyDelegate();
              
              MyDelegate del = this.insertTemplate;
              
              private void sqlQuery(MyDelegate sqlMethod)
              {
               ...
               del();
               ...
              }
              

              【讨论】:

                猜你喜欢
                • 2011-07-21
                • 2018-08-08
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2016-12-21
                • 1970-01-01
                相关资源
                最近更新 更多