Saya menggunakan Linq To XML
new XElement("Prefix", Prefix == null ? "" : Prefix)
tetapi saya ingin melakukan beberapa perhitungan pada awalan sebelum menambahkannya ke xml, seperti menghilangkan spasi, karakter khusus, beberapa perhitungan, dll.
Saya tidak ingin membuat fungsi karena yang ini tidak akan membantu di bagian lain dari program saya tetapi ini, jadi apakah ada cara untuk membuat fungsi sebaris ??
Jawaban:
Ya, C # mendukung itu. Ada beberapa sintaks yang tersedia.
Metode anonim ditambahkan di C # 2.0:
Func<int, int, int> add = delegate(int x, int y) { return x + y; }; Action<int> print = delegate(int x) { Console.WriteLine(x); } Action<int> helloWorld = delegate // parameters can be elided if ignored { Console.WriteLine("Hello world!"); }
Lambda baru dalam C # 3.0 dan tersedia dalam dua rasa.
Ekspresi lambda:
Func<int, int, int> add = (int x, int y) => x + y; // or... Func<int, int, int> add = (x, y) => x + y; // types are inferred by the compiler
Pernyataan lambda:
Action<int> print = (int x) => { Console.WriteLine(x); }; Action<int> print = x => { Console.WriteLine(x); }; // inferred types Func<int, int, int> add = (x, y) => { return x + y; };
Fungsi lokal telah diperkenalkan dengan C # 7.0:
int add(int x, int y) => x + y; void print(int x) { Console.WriteLine(x); }
Pada dasarnya ada dua jenis yang berbeda untuk ini:
Func
danAction
.Func
s mengembalikan nilai tetapiAction
s tidak. Parameter tipe terakhir dari aFunc
adalah tipe kembali; yang lainnya adalah tipe parameter.Ada tipe serupa dengan nama berbeda, tetapi sintaksis untuk mendeklarasikannya sebaris adalah sama. Contohnya adalah
Comparison<T>
, yang secara kasar setara denganFunc<T, T, int>
.Func<string, string, int> compare1 = (l,r) => 1; Comparison<string> compare2 = (l, r) => 1; Comparison<string> compare3 = compare1; // this one only works from C# 4.0 onwards
Ini dapat dipanggil secara langsung seolah-olah itu adalah metode biasa:
int x = add(23, 17); // x == 40 print(x); // outputs 40 helloWorld(x); // helloWorld has one int parameter declared: Action<int> // even though it does not make any use of it.
sumber
C # 7 menambahkan dukungan untuk fungsi lokal
Berikut adalah contoh sebelumnya menggunakan fungsi lokal
void Method() { string localFunction(string source) { // add your functionality here return source ; }; // call the inline function localFunction("prefix"); }
sumber
Jawaban atas pertanyaan Anda adalah ya dan tidak, tergantung apa yang Anda maksud dengan "fungsi sebaris". Jika Anda menggunakan istilah seperti yang digunakan dalam pengembangan C ++ maka jawabannya tidak, Anda tidak dapat melakukannya - bahkan ekspresi lambda adalah panggilan fungsi. Meskipun benar bahwa Anda dapat mendefinisikan ekspresi lambda sebaris untuk menggantikan deklarasi fungsi di C #, kompilator masih akan membuat fungsi anonim.
Berikut beberapa kode yang sangat sederhana yang saya gunakan untuk menguji ini (VS2015):
static void Main(string[] args) { Func<int, int> incr = a => a + 1; Console.WriteLine($"P1 = {incr(5)}"); }
Apa yang dihasilkan kompilator? Saya menggunakan alat bagus yang disebut ILSpy yang menunjukkan perakitan IL sebenarnya yang dihasilkan. Coba lihat (Saya telah menghilangkan banyak hal pengaturan kelas)
Ini adalah fungsi utama:
IL_001f: stloc.0 IL_0020: ldstr "P1 = {0}" IL_0025: ldloc.0 IL_0026: ldc.i4.5 IL_0027: callvirt instance !1 class [mscorlib]System.Func`2<int32, int32>::Invoke(!0) IL_002c: box [mscorlib]System.Int32 IL_0031: call string [mscorlib]System.String::Format(string, object) IL_0036: call void [mscorlib]System.Console::WriteLine(string) IL_003b: ret
Lihat baris tersebut IL_0026 dan IL_0027? Kedua instruksi tersebut memuat angka 5 dan memanggil suatu fungsi. Kemudian format IL_0031 dan IL_0036 dan print hasilnya.
Dan inilah fungsi yang disebut:
.method assembly hidebysig instance int32 '<Main>b__0_0' ( int32 a ) cil managed { // Method begins at RVA 0x20ac // Code size 4 (0x4) .maxstack 8 IL_0000: ldarg.1 IL_0001: ldc.i4.1 IL_0002: add IL_0003: ret } // end of method '<>c'::'<Main>b__0_0'
Ini adalah fungsi yang sangat singkat, tetapi ini adalah fungsi.
Apakah upaya untuk mengoptimalkan ini sepadan? Nah. Mungkin jika Anda memanggilnya ribuan kali per detik, tetapi jika kinerjanya begitu penting maka Anda harus mempertimbangkan untuk memanggil kode asli yang ditulis dalam C / C ++ untuk melakukan pekerjaan itu.
Dalam pengalaman saya, keterbacaan dan pemeliharaan hampir selalu lebih penting daripada mengoptimalkan untuk mendapatkan kecepatan beberapa mikrodetik. Gunakan fungsi untuk membuat kode Anda dapat dibaca dan untuk mengontrol pelingkupan variabel dan tidak mengkhawatirkan kinerja.
"Pengoptimalan prematur adalah akar dari semua kejahatan (atau setidaknya sebagian besar) dalam pemrograman." - Donald Knuth
"Program yang tidak berjalan dengan benar tidak perlu berjalan cepat" - Saya
sumber
Iya.
Anda dapat membuat metode anonim atau ekspresi lambda :
Func<string, string> PrefixTrimmer = delegate(string x) { return x ?? ""; }; Func<string, string> PrefixTrimmer = x => x ?? "";
sumber
code
Func <string, string> PrefixTrimmer = x => x ?? "";code
Saya baru dalam hal ini dan saya benar-benar tidak mengerti betul dokumen MSDNx ?? ""
adalah operator penggabungan nol. msdn.microsoft.com/en-us/library/ms173224.aspxx => (something)
,x
adalah parameter, dan(something)
merupakan nilai kembalian`.Anda dapat menggunakan Func yang merangkum metode yang memiliki satu parameter dan mengembalikan nilai tipe yang ditentukan oleh parameter TResult.
void Method() { Func<string,string> inlineFunction = source => { // add your functionality here return source ; }; // call the inline function inlineFunction("prefix"); }
sumber
Tidak hanya metode di dalam, ini juga dapat digunakan di dalam kelas.
class Calculator { public static int Sum(int x,int y) => x + y; public static Func<int, int, int> Add = (x, y) => x + y; public static Action<int,int> DisplaySum = (x, y) => Console.WriteLine(x + y); }
sumber