Bagaimana cara mengembalikan nilai dari Action ()?

95

Berkenaan dengan jawaban untuk pertanyaan ini Meneruskan DataContext ke Aksi () , bagaimana cara mengembalikan nilai dari aksi (db)?

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

Seharusnya lebih seperti:

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

Jawaban:

100

Metode statis Anda harus mulai dari:

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

Untuk:

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

Jawaban ini muncul dari komentar sehingga saya dapat memberikan kode. Untuk penjelasan selengkapnya, lihat jawaban @ sll di bawah ini.

Kirk Woll
sumber
114

Anda dapat menggunakan Func<T, TResult>delegasi umum. (Lihat MSDN )

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

Juga ada delegasi umum berguna yang mempertimbangkan nilai pengembalian:

  • Converter<TInput, TOutput>( MSDN )
  • Predicate<TInput>- selalu mengembalikan bool ( MSDN )

Metode:

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

Delegasi umum:

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

Menjalankan:

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

ATAU secara eksplisit:

MyType myTypeInstance = SimpleUsing.DoUsing(db => return new MyType());
sll
sumber
6
@LB - meminta orang untuk menggunakan Google tidaklah konstruktif. SO ada untuk memberikan jawaban yang lengkap.
Kirk Woll
5
@KirkWoll Tapi jawabannya memberikan ramuannya , tidak perlu dimasak
LB
9
@LB - lebih baik untuk diselesaikan. Saya menemukan analogi Anda palsu.
Kirk Woll
1
@LB, lebih baik tidak berkomentar karena Anda tidak menambahkan nilai apa pun.
4thSpace
1
@Shn_Android_Dev - Anda benar tetapi Action bukanlah fasilitas untuk mengembalikan nilai, tentunya kita dapat berbalik dan menemukan kembali roda tetapi apakah komplikasi kode seperti itu layak untuk diterapkan pada Action?
sll
15

Anda juga dapat memanfaatkan fakta bahwa lambda atau metode anonim dapat menutup variabel dalam cakupannya.

MyType result;

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

//do something with result
Steve Rowbotham
sumber
ya, ini disebut Penutupan (hal-hal bahasa fungsional yang juga tersedia untuk kita)
sll
4

Gunakan Func<T>daripada Action<T>.

Action<T> bertindak seperti metode void dengan parameter tipe T, sedangkan Func<T> bekerja seperti fungsi tanpa parameter dan yang mengembalikan objek tipe T.

Jika Anda ingin memberikan parameter pada fungsi Anda, gunakan Func<TParameter1, TParameter2, ..., TReturn>.

Ulysses Alves
sumber