2013-07-03 2 views
2

Я хочу передать метод в качестве аргумента для удаления повторяющегося кода из моей программы. Это функциональность я хотел бы:Передача метода в качестве аргумента в другом методе

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()); 

Возможно ли это?

+0

В дополнении к повторяющимся вопросам, у нас также есть [Действие] (http://msdn.microsoft.com/en-us/library/018hxwa8 (ст = vs.110) .aspx) доступно – musefan

+1

Пожалуйста, подумайте об упаковке кода базы данных в использующем блоке, например, используя (SqlConnection connection = new SqlConnection (connectionString)) {...} – DOK

+1

Обратите внимание, что вам будет намного лучше определить ваш объект подключения как локальная переменная в 'sqlQuery' и передача ее в качестве параметра для вашего делегата, вместо того, чтобы делать это поле экземпляра и иметь другие методы, ссылающиеся на соединение, которое они не знают, открыто или нет. Затем вы захотите использовать делегат 'Action ', а не 'Action', и пусть' insertTemplate' принимает соединение в качестве параметра. Это гарантирует, что повсюду, к которому можно получить доступ, вы знаете, что оно открыто. Также можно комбинировать с комментарием DOK. – Servy

ответ

1

Вы можете добиться того, что с делегатом.

Использование, например 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(); 
    } 
} 
4

Используйте делегата Action.

Изменить

private void sqlQuery(Method sqlMethod) 

в

private void sqlQuery(Action sqlMethod) 

и

sqlQuery(insertTemplate()); 

в

sqlQuery(insertTemplate); 
1

Да, но немного отличается ...

Попробуйте это:

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

И объявите SQLQuery так:

private void sqlQuery(Action sqlMethod) 
1

Посмотрите на delegates. В вашем случае, так как ваш метод не принимает никаких параметров, вы можете использовать встроенный в Action делегат:

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

sqlQuery(insertTemplate); 
1

блоки логики в C# передаются как delegates. Есть несколько способов объявить делегат - вы можете определить пользовательскую один, или использовать один из предопределенных типов:

  • Вы можете использовать Action<...> для делегатов, которые не возвращают значения, или
  • Вы можете использовать Func<...,R> для делегаты, которые возвращают значения.

Вот один из способов, чтобы определить функцию, которая принимает делегат:

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

вызова sqlQuery с именем или анонимный делегат, который может быть определен рядным, как по имени метод, или как лямбда выражение:

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

Да.Вам нужно использовать делегаты, анонимные функции или лямбда-выражения.

Вот простой пример:

public void SomeMethod(Action<string> passedMethod) 
{ 
    passedMethod("some string"); 
} 

public void Caller() 
{ 
    SomeMethod(x => Console.WriteLine(x)); 
} 

Если вы запустите «Абонент», он будет выводить «некоторые строки».

0

Делегаты ответ ->Microsoft on C# Delegates

public void delegate MyDelegate(); 

MyDelegate del = this.insertTemplate; 

private void sqlQuery(MyDelegate sqlMethod) 
{ 
... 
del(); 
... 
} 
Смежные вопросы