{"id":767,"date":"2019-04-25T19:21:22","date_gmt":"2019-04-25T19:21:22","guid":{"rendered":"http:\/\/www.smart-bricks.net\/?p=767"},"modified":"2019-04-28T22:23:11","modified_gmt":"2019-04-28T22:23:11","slug":"c-futures-lambda-attributes","status":"publish","type":"post","link":"http:\/\/www.smart-bricks.net\/index.php\/2019\/04\/25\/c-futures-lambda-attributes\/","title":{"rendered":"C# Futures: Lambda Attributes"},"content":{"rendered":"\n<p>Attributes are a key part of .NET\u2019s metadata processing \ncapabilities. They are used by compilers, static analyzers, and runtime \nlibraries for a variety of purposes. While normal functions\/methods can \nhave attributes, prior to this proposal lambdas and anonymous functions \ncould not.<\/p>\n\n\n\n<p>While in theory any attribute applicable to normal functions\/methods \ncould be applied to a lambda, there are new attributes being considered \nspecifically for them. These new attributes control what can be captured\n by the lambda.<\/p>\n\n\n\n<ul><li>CaptureNone: No variables can be captured. The lambda will be compiled as a static function.<\/li><li>CaptureThis: Only the \u2018this\u2019 pointer will be captured. The lambda will be compiled as a method.<\/li><li>CaptureAny: Any local variable can be captured. The lambda will be compiled as part of an anonymous closure object.<\/li><\/ul>\n\n\n\n<p>When working with performance sensitive code, CaptureAny should be \navoided because a new delegate and matching closure object need to be \ncreated for each instance. CaptureThis isn\u2019t as bad, but a new delegate \nstill must be allocated. This delegate could result in inefficient \nmemory use if it keeps the outer object alive longer than otherwise \nnecessary. Finally, CaptureNone would only need to create one instance \nof a delegate that could be reused throughout the life of the \napplication.<\/p>\n\n\n\n<p>When applied to a lambda, the attributes would be used by the \ncompiler or an analyzer to ensure a CaptureNone lambda isn\u2019t \naccidentally changed to a less efficient type in the future. Essentially\n the attributes would act as a form of documentation.<\/p>\n\n\n\n<p>This concept isn\u2019t new. For example, in <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/lambda\">C++ lambdas<\/a>\n one has to explicitly list all variables the lambda can capture. The \ndifference here is that the attributes would be optional in C# (unless \notherwise enforced by an analyzer).<\/p>\n\n\n\n<p>Under this proposal, attributes can also be added to the parameters \non a lambda. In order to avoid confusion, parameters must be enclosed in\n parens when using attributes. If the attribute is also inside the \nparen, it applies to the parameter. Attributes outside of the parens \napply to the lambda as a whole.<\/p>\n\n\n\n<p>For more information see the <a href=\"https:\/\/github.com\/dotnet\/csharplang\/blob\/master\/proposals\/lambda-attributes.md\">Lambda Attributes proposal<\/a> on GitHub.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Attributes are a key part of .NET\u2019s metadata processing capabilities. They are used by compilers, static analyzers, and runtime libraries for a variety of purposes. While normal functions\/methods can have attributes, prior to this proposal lambdas and anonymous functions could not. While in theory any attribute applicable to normal functions\/methods could be applied to a&hellip;&nbsp;<a href=\"http:\/\/www.smart-bricks.net\/index.php\/2019\/04\/25\/c-futures-lambda-attributes\/\" class=\"\" rel=\"bookmark\">Read More &raquo;<span class=\"screen-reader-text\">C# Futures: Lambda Attributes<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[21,14],"_links":{"self":[{"href":"http:\/\/www.smart-bricks.net\/index.php\/wp-json\/wp\/v2\/posts\/767"}],"collection":[{"href":"http:\/\/www.smart-bricks.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.smart-bricks.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.smart-bricks.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.smart-bricks.net\/index.php\/wp-json\/wp\/v2\/comments?post=767"}],"version-history":[{"count":1,"href":"http:\/\/www.smart-bricks.net\/index.php\/wp-json\/wp\/v2\/posts\/767\/revisions"}],"predecessor-version":[{"id":768,"href":"http:\/\/www.smart-bricks.net\/index.php\/wp-json\/wp\/v2\/posts\/767\/revisions\/768"}],"wp:attachment":[{"href":"http:\/\/www.smart-bricks.net\/index.php\/wp-json\/wp\/v2\/media?parent=767"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.smart-bricks.net\/index.php\/wp-json\/wp\/v2\/categories?post=767"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.smart-bricks.net\/index.php\/wp-json\/wp\/v2\/tags?post=767"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}