Як повернути значення з Action ()?


92

Що стосується відповіді на це запитання Передання DataContext у дію () , як повернути значення з дії (db)?

SimpleUsing.DoUsing(db => { 
// do whatever with db 
}); 

Має бути більше схожим на:

MyType myType = SimpleUsing.DoUsing<MyType>(db => { 
// do whatever with db.  query buit using db returns MyType.
}); 

Відповіді:


97

Ваш статичний метод повинен переходити з:

public static class SimpleUsing
{
    public static void DoUsing(Action<MyDataContext> action)
    {
        using (MyDataContext db = new MyDataContext())
           action(db);
    }
}

Кому:

public static class SimpleUsing
{
    public static TResult DoUsing<TResult>(Func<MyDataContext, TResult> action)
    {
        using (MyDataContext db = new MyDataContext())
           return action(db);
    }
}

Ця відповідь виросла із коментарів, щоб я міг надати код. Повне опрацювання див. У відповіді @ sll нижче.


113

Ви можете використовувати Func<T, TResult>загальний делегат. (Див. MSDN )

Func<MyType, ReturnType> func = (db) => { return new MyType(); }

Також є корисні загальні делегати, які вважають повернене значення:

  • Converter<TInput, TOutput>( MSDN )
  • Predicate<TInput>- завжди повертати bool ( MSDN )

Метод:

public MyType SimpleUsing.DoUsing<MyType>(Func<TInput, MyType> myTypeFactory)

Загальний делегат:

Func<InputArgumentType, MyType> createInstance = db => return new MyType();

Виконати:

MyType myTypeInstance = SimpleUsing.DoUsing(
                            createInstance(new InputArgumentType()));

АБО явно:

MyType myTypeInstance = SimpleUsing.DoUsing(db => return new MyType());

Правильно - можете навести приклад того, як повинен виглядати метод?
4thSpace

5
@LB - просити людей гуглити не є конструктивним. ТАК існує для надання повних відповідей.
Kirk Woll

5
@KirkWoll Але відповідь дає інгредієнти , це не потрібно готувати
LB

9
@LB - краще, щоб він був повним. Я вважаю вашу аналогію хибною.
Kirk Woll,

1
@LB, краще не коментувати, оскільки ти ніколи не додаєш жодної цінності.
4thSpace

15

Ви також можете скористатися тим фактом, що лямбда-або анонімний метод може закрити змінні у своїй обширній області дії.

MyType result;

SimpleUsing.DoUsing(db => 
{
  result = db.SomeQuery(); //whatever returns the MyType result
}); 

//do something with result

так, це називається Закриттям (функціональні мовні матеріали, які доступні і для нас)
sll

4

Використовуйте, Func<T>а не Action<T>.

Action<T>діє як метод void з параметром типу T, тоді як Func<T>працює як функція без параметрів і яка повертає об'єкт типу T.

Якщо ви хочете задати параметри своїй функції, використовуйте Func<TParameter1, TParameter2, ..., TReturn>.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.