﻿
{"id":19407,"date":"2021-01-25T12:25:41","date_gmt":"2021-01-25T12:25:41","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=19407"},"modified":"2021-01-25T12:25:41","modified_gmt":"2021-01-25T12:25:41","slug":"c-9-0-static-anonymous-functions","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/c-9-0-static-anonymous-functions\/","title":{"rendered":"C# 9.0 &#8211; Static Anonymous Functions"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Nas\u0131l ki, be\u015feri bir dilin keskinli\u011fi, o dilin belagat ve fesahata olan yatk\u0131nl\u0131\u011f\u0131na, belagat ve fesahata olan yatk\u0131nl\u0131\u011f\u0131 ise ilgili dilin tarihsel dokusuna yani bir ba\u015fka deyi\u015fle temas etti\u011fi insanl\u0131k tecr\u00fcbesine ba\u011fl\u0131, benzer mant\u0131kla \u00e7a\u011f\u0131m\u0131z\u0131n soyut zihinleri olan yaz\u0131l\u0131mlar\u0131n kendi d\u00fcnyalar\u0131ndaki dillerinin g\u00fcc\u00fc; kaynaklar \u00fczerindeki hakimiyet alanlar\u0131na, hakimiyet alanlar\u0131 ise dilin temas edebildi\u011fi nazik noktalara ba\u011fl\u0131d\u0131r. Buradaki metafordan yola \u00e7\u0131karak, ister be\u015feri olsun ister suni, bir dilin gelece\u011fe hitap edecek olan t\u00fcm kelamlara sahip olabildi\u011fini g\u00f6steren en b\u00fcy\u00fck delili, davran\u0131\u015f\u0131n\u0131n her bir noktas\u0131na m\u00fcdahale edilebilirlik derecesidir diyebiliriz. \u0130\u015fte C#, 9.0 versiyonuyla programlama d\u00fcnyas\u0131nda gelece\u011fe g\u00f6z k\u0131rpmakta ve g\u00fcc\u00fcn\u00fc, hakimiyetini ve temas edebildi\u011fi noktalar\u0131 bir t\u0131k daha artt\u0131rarak yeni bir \u00f6zellik ile g\u00fcn\u00fcm\u00fcze dokunmaktad\u0131r.<\/p>\n<p><strong><em>Peki nedir bu \u00f6zellik?<\/em><\/strong><br \/>\nKlasik bir C# kodunu inceledi\u011finizde y\u00fcksek ihtimal <a href=\"https:\/\/www.gencayyildiz.com\/blog\/lambda-ifadeleri-lambda-expressions\/\" rel=\"noopener noreferrer\" target=\"_blank\">lambda expression<\/a>&#8216;lar\u0131n yo\u011fun bir \u015fekilde kullan\u0131ld\u0131\u011f\u0131n\u0131 g\u00f6rmeniz kuvvetle muhtemel. Lambda ifadeleri yap\u0131sal olarak bir temsilci taraf\u0131ndan i\u015faretlenmesi gereken metodun boilerplate(basmakal\u0131p) olarak imzas\u0131n\u0131n ve g\u00f6vdesinin tan\u0131mlanmas\u0131ndan biz developer&#8217;\u0131 kurtaran ve h\u0131zl\u0131 bir \u015fekilde ilgili fonksiyonu olu\u015fturarak, daha d\u00fczg\u00fcn ve estetik bir \u015fekilde kodun geli\u015ftirilmesini sa\u011flayan yap\u0131lard\u0131r. Lakin bu \u015fekilde developer a\u00e7\u0131s\u0131ndan b\u00fcy\u00fck avantaj\u0131 olan bu lambda ifadelerinin esas\u0131nda bellek optimizasyonu a\u00e7\u0131s\u0131ndan olduk\u00e7a maliyetli olabileceklerini hi\u00e7 d\u00fc\u015f\u00fcnd\u00fcn\u00fcz m\u00fc?.<\/p>\n<p><em>Nas\u0131l yani?<\/em> <\/p>\n<p>\u015e\u00f6yle ki, LINQ sorgular\u0131n\u0131 kullan\u0131rken yahut farkl\u0131 bir thread&#8217;de operasyonlar\u0131 ele almaya \u00e7al\u0131\u015f\u0131rken s\u0131k s\u0131k ba\u015fvurdu\u011fumuz lambda expression&#8217;lar kullan\u0131m durumlar\u0131na g\u00f6re ister istemez bellekte l\u00fczumsuz maliyetlere sebebiyet verebilmektedirler. Bu durumu a\u015fa\u011f\u0131daki kod \u00fczerinden \u00f6rneklendirelim;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    class Program\r\n    {\r\n        static void Main(string&#x5B;] args)\r\n        {\r\n            int a = 5;\r\n            Action action = () =&gt; { a *= 5; };\r\n            action.Invoke();\r\n        }\r\n    }\r\n<\/pre>\n<p>Yukar\u0131daki kod blo\u011funu incelerseniz e\u011fer, bir adet &#8216;Action&#8217; delegasyonu ile temsil edilen lambda fonksiyonu ve bu fonksiyon i\u00e7erisinde kullan\u0131lan &#8216;Main&#8217; i\u00e7erisinde tan\u0131mlanm\u0131\u015f olan &#8216;int&#8217; de\u011fi\u015fkenini g\u00f6rmektesiniz.<\/p>\n<p><em>Eee hoca, bunun neresinde maliyet?<\/em><\/p>\n<p>G\u00f6r\u00fcn\u00fcrde maliyet yokmu\u015f gibi bir durum olsa da, esas\u0131nda bu kodu derledi\u011fimizde maliyet ortaya \u00e7\u0131kmaktad\u0131r. Derleme neticesinde, compiler &#8216;<em>closure<\/em>&#8216; isminde bir s\u0131n\u0131f olu\u015fturacak ve bu s\u0131n\u0131f \u00fczerinde ilgili lambda fonksiyonunu normal metot olarak ekleyecektir. Bir yandan da bu metot i\u00e7erisinde eri\u015filecek olan de\u011fi\u015fkeni, s\u00f6z konusu s\u0131n\u0131fa field olarak ekleyecektir. Tabi ger\u00e7ekle\u015ftirilmesi gereken operasyonu sa\u011flayabilmek i\u00e7in ilgili s\u0131n\u0131ftan bir nesne \u00fcretecek ve field&#8217;a de\u011feri ne ise(5) verecektir. Haliyle compile s\u00fcrecinde bu \u015fekilde bir davran\u0131\u015f sergileyecek olan yukar\u0131daki lambda fonksiyonunu, herhangi bir d\u00f6ng\u00fc yahut farkl\u0131 \u015fekillerle birden fazla kez tetiklemi\u015f olsayd\u0131k, tetikleme say\u0131s\u0131 kadar nesne olu\u015fturulaca\u011f\u0131 i\u00e7in bu durum Garbage Collector a\u00e7\u0131s\u0131ndan pek i\u00e7 a\u00e7\u0131c\u0131 olmayacakt\u0131r. \u0130\u015fte maliyette tam da buradad\u0131r!<\/p>\n<p>Yukar\u0131daki yap\u0131lan operasyonu a\u015fa\u011f\u0131daki gibi ele al\u0131rsak:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    class Program\r\n    {\r\n        static void Main(string&#x5B;] args)\r\n        {\r\n            Action action = () =&gt;\r\n            {\r\n                int a = 5;\r\n                a *= 5;\r\n            };\r\n            action.Invoke();\r\n        }\r\n    }\r\n<\/pre>\n<p>B\u00f6yle bir durumda ise, tan\u0131mlanan lambda expression taraf\u0131ndan d\u0131\u015far\u0131daki herhangi bir de\u011fi\u015fkene eri\u015fim ger\u00e7ekle\u015ftirilmedi\u011finden dolay\u0131 \u00fcretilecek olan &#8216;<em>closure<\/em>&#8216; isimli s\u0131n\u0131f\u0131n i\u00e7erisinde ilgili de\u011fi\u015fken bir static field olarak eklenecektir ve b\u00f6ylece ilgili kod her tetiklendi\u011finde esas\u0131nda bellekte(statik) tutulan ayn\u0131 de\u011fer d\u00f6nd\u00fcr\u00fclecektir. B\u00f6ylece \u00f6nceki senaryoya istinaden bellek optimizasyonu a\u00e7\u0131s\u0131ndan arada baya\u011f\u0131 bir fark oldu\u011funu s\u00f6yleyebiliriz&#8230; <em>\u00d6yle de\u011fil mi?<\/em><\/p>\n<blockquote><p><em style=\"color:orange;\">G\u00fcnl\u00fck hayatta lambda ifadelerini s\u0131k\u00e7a kulland\u0131\u011f\u0131m\u0131z LINQ fonksiyonlar\u0131nda b\u00fcy\u00fck oranda d\u0131\u015far\u0131dan al\u0131nan parametrelerle i\u015flevler ger\u00e7ekle\u015ftirilmektedir. Bu duruma bellek optimizasyonu a\u00e7\u0131s\u0131ndan m\u00fcdahale etme \u015fans\u0131m\u0131z pek bulunmamakta ve hatta i\u015fin kolayl\u0131\u011f\u0131ndan \u00f6t\u00fcr\u00fc getirisinden dolay\u0131 bu maliyet g\u00f6z ard\u0131 edilmektedir.<\/em><\/p><\/blockquote>\n<p><strong><em>Peki hoca! Lambda expression&#8217;larda ki bu l\u00fczumsuz alan tahsisini \u00f6nlemenin yolu yok mu?<\/em><\/strong><br \/>\nTabi ki de k\u0131smi de olsa bir optimizasyon \u015fans\u0131 s\u00f6z konusudur diyebiliriz. Bunun i\u00e7in lambda i\u00e7erisinde kullan\u0131lacak ilgili de\u011fi\u015fkenleri lambda&#8217;ya parametre olarak aktarmak yeterli olacakt\u0131r.<\/p>\n<p>\u015e\u00f6yle ki;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    class Program\r\n    {\r\n        static void Main(string&#x5B;] args)\r\n        {\r\n            MyClass myClass = new MyClass();\r\n            Action action = () =&gt;\r\n            {\r\n                myClass.MyProperty *= 5;\r\n            };\r\n            action.Invoke();\r\n        }\r\n    }\r\n    class MyClass\r\n    {\r\n        public int MyProperty { get; set; }\r\n    }\r\n<\/pre>\n<p>Konuyu daha da zenginle\u015ftirmek i\u00e7in yukar\u0131daki farkl\u0131 \u00f6rne\u011fi ele al\u0131rsak, lambda expression d\u0131\u015f\u0131nda tan\u0131mlanm\u0131\u015f olan bir property&#8217;e eri\u015fim sa\u011fland\u0131\u011f\u0131ndan dolay\u0131 bu durum l\u00fczumsuz tahsise neden oluyordu. Bu kodu a\u015fa\u011f\u0131daki gibi geli\u015ftirirsek e\u011fer;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    class Program\r\n    {\r\n        static void Main(string&#x5B;] args)\r\n        {\r\n            MyClass myClass = new MyClass();\r\n            Action&lt;MyClass&gt; action = obj =&gt;\r\n            {\r\n                obj.MyProperty *= 5;\r\n            };\r\n            action.Invoke(myClass);\r\n        }\r\n    }\r\n    class MyClass\r\n    {\r\n        public int MyProperty { get; set; }\r\n    }\r\n<\/pre>\n<p>G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere ilgili lambda ifade d\u0131\u015far\u0131dan herhangi bir de\u011fi\u015fkene eri\u015fmeye \u00e7al\u0131\u015fmad\u0131\u011f\u0131ndan ekstradan bir bellek tahsisi yap\u0131lmamakta ve daha optimize bir kod in\u015fa edilmi\u015f olmaktad\u0131r.<\/p>\n<p>Tabi burada &#8216;MyClass&#8217; t\u00fcr\u00fcne ba\u011fl\u0131 olmaktansa daha evrensel bir \u015fekilde bu kodu geli\u015ftirmek isteyebiliriz :<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    class Program\r\n    {\r\n        static void Main(string&#x5B;] args)\r\n        {\r\n            MyClass myClass = new MyClass();\r\n            Lambda.Call&lt;MyClass&gt;(myClass, obj =&gt; obj.MyProperty *= 5);\r\n        }\r\n    }\r\n    class MyClass\r\n    {\r\n        public int MyProperty { get; set; }\r\n    }\r\n    static class Lambda\r\n    {\r\n        static public void Call&lt;T&gt;(T obj, Action&lt;T&gt; action)\r\n         =&gt; action.Invoke(obj);\r\n    }\r\n<\/pre>\n<p>B\u00f6ylece &#8216;Lambda&#8217; s\u0131n\u0131f\u0131 i\u00e7erisindeki generic &#8216;Call&#8217; fonksiyonu sayesinde t\u00fcrden ba\u011f\u0131ms\u0131z bir \u015fekilde optimize edilmi\u015f lambda operasyonlar\u0131n\u0131 kullanabilmekteyiz. Burada dikkat ederseniz optimize edilmi\u015f ileri seviye bir yakla\u015f\u0131m sergilenmektedir. Bu ve buna benzer yakla\u015f\u0131mlar\u0131 <code style=\"color:red;\">string.Create<\/code> gibi baz\u0131 metinsel fonksiyonlarda kullan\u0131ld\u0131\u011f\u0131n\u0131 g\u00f6rebilirsiniz.<\/p>\n<blockquote><p><em style=\"color:orange;\">LINQ sorgular\u0131nda ki yersiz alan tahsislerine kar\u015f\u0131 alternatif olarak d\u00f6ng\u00fcleri kullanabilirsiniz. Tabi bu zahmette karar sizin! \ud83d\ude42<\/em><\/p><\/blockquote>\n<p>T\u00fcm bu optimizasyonlu yap\u0131lanmalar\u0131n d\u0131\u015f\u0131nda, insanl\u0131k hallerine denk gelip fark\u0131nda olmadan lambda ifadelerinin d\u0131\u015f\u0131ndaki de\u011fi\u015fkenlere eri\u015fim sa\u011flanmas\u0131 ihtimallerini s\u0131f\u0131ra indirebilmek ve kesinlikle bu tarz bellek israflar\u0131na yol a\u00e7an t\u00fcm \u00e7al\u0131\u015fmalar\u0131 engelleyebilmek i\u00e7in esas bu makalenin konusu olan C# 9.0 ile gelen <u><em>Static Lambda<\/em><\/u> \u00f6zelli\u011fini kullanabiliriz.<\/p>\n<p>Haliyle bir lambda ifadeyi &#8216;static&#8217; keyword\u00fc ile a\u015fa\u011f\u0131daki gibi i\u015faretlersek e\u011fer;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n            Action action = static () =&gt; { };\r\n<\/pre>\n<p>lambda d\u0131\u015f\u0131ndaki hi\u00e7bir de\u011fi\u015fkene eri\u015filemeyece\u011fini derleyici a\u00e7\u0131s\u0131ndan garanti alt\u0131na alm\u0131\u015f oluyoruz.<\/p>\n<div id=\"attachment_20719\" style=\"width: 661px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/C-9.0-Static-Anonymous-Functions.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-20719\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/C-9.0-Static-Anonymous-Functions.png\" alt=\"C# 9.0 - Static Anonymous Functions\" width=\"651\" height=\"110\" class=\"size-full wp-image-20719\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/C-9.0-Static-Anonymous-Functions.png 651w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/C-9.0-Static-Anonymous-Functions-300x51.png 300w\" sizes=\"auto, (max-width: 651px) 100vw, 651px\" \/><\/a><p id=\"caption-attachment-20719\" class=\"wp-caption-text\">Static Lambda taraf\u0131ndan d\u0131\u015far\u0131da tan\u0131mlanm\u0131\u015f bir de\u011fi\u015fkene eri\u015fmeye \u00e7al\u0131\u015f\u0131ld\u0131\u011f\u0131nda al\u0131nan hata.<br \/>&#8220;A static anonymous function cannot contain a reference to &#8216;a&#8217;.&#8221;<\/p><\/div>\n<p>B\u00f6ylece C# programlama dilinin en esnek yap\u0131lar\u0131ndan biri olan lambda ifadelerinin i\u00e7erisinde fark\u0131nda olal\u0131m ya da olmayal\u0131m ekstradan bellekte allocation(tahsis)&#8217;lara sebep olabilen durumlar\u0131 ele alm\u0131\u015f ve bu durumlara kar\u015f\u0131 nas\u0131l duru\u015f sergileyebilece\u011fimizi \u00f6rneklerle de\u011ferlendirmi\u015f ve isti\u015fare eylemi\u015f olduk&#8230;<\/p>\n<p>\u0130lgilenenlerin faydalanmas\u0131 dile\u011fiyle&#8230;<br \/>\nSonraki yaz\u0131lar\u0131mda g\u00f6r\u00fc\u015fmek \u00fczere&#8230;<br \/>\n\u0130yi \u00e7al\u0131\u015fmalar&#8230;<\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, Nas\u0131l ki, be\u015feri bir dilin keskinli\u011fi, o dilin belagat ve fesahata olan yatk\u0131nl\u0131\u011f\u0131na, belagat ve fesahata olan yatk\u0131nl\u0131\u011f\u0131 ise ilgili dilin tarihsel dokusuna yani bir ba\u015fka deyi\u015fle temas etti\u011fi insanl\u0131k tecr\u00fcbesine ba\u011fl\u0131, benzer&#46;&#46;&#46;<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":19209,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2739,12,3928],"tags":[3929,4107,4111,4110,4109,4106,4108],"class_list":["post-19407","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net-core","category-c-sharp-c","category-c-9-0","tag-c-9-0","tag-c-9-0-static-anonymous-functions","tag-c-9-0-yenilikleri","tag-c-lambda-expression","tag-c-static-lambda","tag-static-anonymous-functions","tag-static-lambda"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/19407","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/comments?post=19407"}],"version-history":[{"count":32,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/19407\/revisions"}],"predecessor-version":[{"id":20723,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/19407\/revisions\/20723"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/19209"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=19407"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=19407"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=19407"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}