Back in 2005, with the release of C# 2.0 standard we got a possibility to pass a variable to the body of an anonymous delegate by capturing it from the current context. In 2008 the C# 3.0 brought us lambdas, user anonymous classes, LINQ requests and much more. Now it January, 2017 and the majority of C# developers are looking forward to the release of the C# 7.0 standard that should provide us a bunch of new useful features. However, there are still old features that need to be fixed. That's why there are plenty of ways to shoot yourself in the foot. Today we are going to speak about one of them, and it is related with quite an unobvious mechanism of variable capture in the body of anonymous functions in C#.
One of the programs, which allows you to solve the problem of data compression, is a popular file archiver 7-Zip, which I often use myself. Our readers have long asked us to check the code of this application. Well, it's time to look at its source code, and see what PVS-Studio is able to detect in this application.
Every now and then, we have to write articles about how we've checked another fresh version of some compiler. That's not really much fun. However, as practice shows, if we stop doing that for a while, folks start doubting whether PVS-Studio is worth its title of a good catcher of bugs and vulnerabilities. What if the new compiler can do that too? Sure, compilers evolve, but so does PVS-Studio – and it proves, again and again, its ability to catch bugs even in high-quality projects such as compilers.
Checking the Source Code of FlashDevelop with PVS-StudioPVS-Studio
To assess the quality of our static analyzer's diagnostics and to advertise it, we regularly analyze various open-source projects. The developers of FlashDevelop project contacted us on their own initiative and asked us to check their product, which we have gladly done.
ChakraCore: analysis of JavaScript-engine for Microsoft EdgePVS-Studio
On the JSConf US conference in December 2015 the developers announced that they were planning to make open the source code of Chakra key components, a JavaScript-engine, operating in Microsoft Edge. Recently the ChackraCore source code became available under the MIT license in the corresponding repository on GitHub. In this article you will find interesting code fragments that were detected with the help of PVS-Studio code analyzer.
The Chromium browser is developing very fast. When we checked the solution for the first time in 2011, it included 473 projects. Now it includes 1169 projects. We were curious to know if Google developers had managed to keep the highest quality of their code with Chromium developing at such a fast rate. Well, they had.
I use this slide deck in C# trainings to cover P/Invoke. Sample code can be found at https://github.com/rstropek/Samples/tree/master/PInvoke For details see my blog at http://www.software-architects.at
Generic programming is a style of computer programming in which algorithms are written in terms of types to-be-specified-later that are then instantiated when needed for specific types provided as parameters.
Generics are a facility of generic programming that were added to the Java programming language in 2004 within version J2SE 5.0. They were designed to extend Java's type system to allow “a type or method to operate on objects of various types while providing compile-time type safety”
The Java collections framework supports generics to specify the type of objects stored in a collection instance.
One of the programs, which allows you to solve the problem of data compression, is a popular file archiver 7-Zip, which I often use myself. Our readers have long asked us to check the code of this application. Well, it's time to look at its source code, and see what PVS-Studio is able to detect in this application.
Every now and then, we have to write articles about how we've checked another fresh version of some compiler. That's not really much fun. However, as practice shows, if we stop doing that for a while, folks start doubting whether PVS-Studio is worth its title of a good catcher of bugs and vulnerabilities. What if the new compiler can do that too? Sure, compilers evolve, but so does PVS-Studio – and it proves, again and again, its ability to catch bugs even in high-quality projects such as compilers.
Checking the Source Code of FlashDevelop with PVS-StudioPVS-Studio
To assess the quality of our static analyzer's diagnostics and to advertise it, we regularly analyze various open-source projects. The developers of FlashDevelop project contacted us on their own initiative and asked us to check their product, which we have gladly done.
ChakraCore: analysis of JavaScript-engine for Microsoft EdgePVS-Studio
On the JSConf US conference in December 2015 the developers announced that they were planning to make open the source code of Chakra key components, a JavaScript-engine, operating in Microsoft Edge. Recently the ChackraCore source code became available under the MIT license in the corresponding repository on GitHub. In this article you will find interesting code fragments that were detected with the help of PVS-Studio code analyzer.
The Chromium browser is developing very fast. When we checked the solution for the first time in 2011, it included 473 projects. Now it includes 1169 projects. We were curious to know if Google developers had managed to keep the highest quality of their code with Chromium developing at such a fast rate. Well, they had.
I use this slide deck in C# trainings to cover P/Invoke. Sample code can be found at https://github.com/rstropek/Samples/tree/master/PInvoke For details see my blog at http://www.software-architects.at
Generic programming is a style of computer programming in which algorithms are written in terms of types to-be-specified-later that are then instantiated when needed for specific types provided as parameters.
Generics are a facility of generic programming that were added to the Java programming language in 2004 within version J2SE 5.0. They were designed to extend Java's type system to allow “a type or method to operate on objects of various types while providing compile-time type safety”
The Java collections framework supports generics to specify the type of objects stored in a collection instance.
SpringOne Platform 2017
Sébastien Deleuze, Pivotal
"In this new talk, I will explain why Spring <3 Kotlin and how you can leverage Spring official support for Kotlin (in Framework, Boot, Data) to build your next Spring project more efficiently and with more pleasure.
I will describe gradually how you can transform your Spring Boot 1.0 Java + Javascript project with into a Spring Boot 2.0 pure Kotlin project running on top of the new WebFlux functional web framework."
Writing software for a virtual machine enables developers to forget about machine code assembly, interrupts, and processor caches. This makes Java a convenient language, but all too many developers see the JVM as a black box and are often unsure of how to optimize their code for performance. This unfortunately adds credence to the myth that Java is always outperformed by native languages. This session takes a peek at the inner workings of Oracle’s HotSpot virtual machine, its just-in-time compiler, and the interplay with a computer’s hardware. From this, you will understand the more common optimizations a virtual machine applies, to be better equipped to improve and reason about a Java program’s performance and how to correctly measure runtime!
In this article, we will speak about the static analysis of the doxygen documentation generator tool. This popular and widely used project, which, as its authors claim, not without reason, has become "the de facto standard tool for generating documentation from annotated C++ sources", has never been scanned by PVS-Studio before. Doxygen scans the program source code and generates the documentation relying on it. Now it's time for us to peep into its source files and see if PVS-Studio can find any interesting bugs there.
At first glance, Java byte code can appear to be some low level magic that is both hard to understand and effectively irrelevant to application developers. However, neither is true. With only little practice, Java byte code becomes easy to read and can give true insights into the functioning of a Java program. In this talk, we will cast light on compiled Java code and its interplay with the Java virtual machine. In the process, we will look into the evolution of byte code over the recent major releases with features such as dynamic method invocation which is the basis to Java 8 lambda expressions. Finally, we will learn about tools for the run time generation of Java classes and how these tools are used to build modern frameworks and libraries. Among those tools, I present Byte Buddy, an open source tool of my own efforts and an attempt to considerably simplify run time code generation in Java. (http://bytebuddy.net)
Checking the Cross-Platform Framework Cocos2d-xAndrey Karpov
Cocos2d is an open source software framework. It can be used to build games, apps and other cross-platform GUI based interactive programs. Cocos2d contains many branches with the best known being Cocos2d-Swift, Cocos2d-x, Cocos2d-html5 and Cocos2d-XNA.
In this article, we are going to discuss results of the check of Cocos2d-x, the framework for C++, done by PVS-Studio 5.18. The project is pretty high-quality, but there are still some issues to consider. The source code was downloaded from GitHub.
Orchard is a free, open source, community-focused Content Management System built on the ASP.NET MVC platform. Software IP management and project development governance are provided by Outercurve Foundation, a nonprofit fund.
PVS-Studio analyzer is continuously improving, and the C#-code analysis module is developing most actively: ninety new diagnostic rules were added in 2016. However, the best way to estimate the analyzer's efficiency is to look at the bugs it can catch. It's always interesting, as well as useful, to do recurring checks of large open-source projects at certain intervals and compare their results. Today I will talk about the results of the second analysis of SharpDevelop project.
Esperanto, Loglan and Dothraki: Why do people construct new languages?Melanie JI Mueller
Did you know that there’s a language that can be played on musical instruments? That there are native speakers of Esperanto? That there’s a language with only 120 root-words? That languages were designed to test a scientific hypothesis? In this talk, I’ll give a short tour through the colorful and eccentric world of constructed languages, and the reasons behind them. I’ll end with a mini crash course in Esperanto.
SpringOne Platform 2017
Sébastien Deleuze, Pivotal
"In this new talk, I will explain why Spring <3 Kotlin and how you can leverage Spring official support for Kotlin (in Framework, Boot, Data) to build your next Spring project more efficiently and with more pleasure.
I will describe gradually how you can transform your Spring Boot 1.0 Java + Javascript project with into a Spring Boot 2.0 pure Kotlin project running on top of the new WebFlux functional web framework."
Writing software for a virtual machine enables developers to forget about machine code assembly, interrupts, and processor caches. This makes Java a convenient language, but all too many developers see the JVM as a black box and are often unsure of how to optimize their code for performance. This unfortunately adds credence to the myth that Java is always outperformed by native languages. This session takes a peek at the inner workings of Oracle’s HotSpot virtual machine, its just-in-time compiler, and the interplay with a computer’s hardware. From this, you will understand the more common optimizations a virtual machine applies, to be better equipped to improve and reason about a Java program’s performance and how to correctly measure runtime!
In this article, we will speak about the static analysis of the doxygen documentation generator tool. This popular and widely used project, which, as its authors claim, not without reason, has become "the de facto standard tool for generating documentation from annotated C++ sources", has never been scanned by PVS-Studio before. Doxygen scans the program source code and generates the documentation relying on it. Now it's time for us to peep into its source files and see if PVS-Studio can find any interesting bugs there.
At first glance, Java byte code can appear to be some low level magic that is both hard to understand and effectively irrelevant to application developers. However, neither is true. With only little practice, Java byte code becomes easy to read and can give true insights into the functioning of a Java program. In this talk, we will cast light on compiled Java code and its interplay with the Java virtual machine. In the process, we will look into the evolution of byte code over the recent major releases with features such as dynamic method invocation which is the basis to Java 8 lambda expressions. Finally, we will learn about tools for the run time generation of Java classes and how these tools are used to build modern frameworks and libraries. Among those tools, I present Byte Buddy, an open source tool of my own efforts and an attempt to considerably simplify run time code generation in Java. (http://bytebuddy.net)
Checking the Cross-Platform Framework Cocos2d-xAndrey Karpov
Cocos2d is an open source software framework. It can be used to build games, apps and other cross-platform GUI based interactive programs. Cocos2d contains many branches with the best known being Cocos2d-Swift, Cocos2d-x, Cocos2d-html5 and Cocos2d-XNA.
In this article, we are going to discuss results of the check of Cocos2d-x, the framework for C++, done by PVS-Studio 5.18. The project is pretty high-quality, but there are still some issues to consider. The source code was downloaded from GitHub.
Orchard is a free, open source, community-focused Content Management System built on the ASP.NET MVC platform. Software IP management and project development governance are provided by Outercurve Foundation, a nonprofit fund.
PVS-Studio analyzer is continuously improving, and the C#-code analysis module is developing most actively: ninety new diagnostic rules were added in 2016. However, the best way to estimate the analyzer's efficiency is to look at the bugs it can catch. It's always interesting, as well as useful, to do recurring checks of large open-source projects at certain intervals and compare their results. Today I will talk about the results of the second analysis of SharpDevelop project.
Esperanto, Loglan and Dothraki: Why do people construct new languages?Melanie JI Mueller
Did you know that there’s a language that can be played on musical instruments? That there are native speakers of Esperanto? That there’s a language with only 120 root-words? That languages were designed to test a scientific hypothesis? In this talk, I’ll give a short tour through the colorful and eccentric world of constructed languages, and the reasons behind them. I’ll end with a mini crash course in Esperanto.
Dear Investors!
I would like to share you some information relating NAMI Corp , a company had listed in NASDAQ's OTC.
Contact : Anthony Stock . Mr.
Email: sokha.biz168@gmail.com
H/P: (855) 87 600 999/ 17 669 799.
Why even small town tourism partners need to be on social media, how they can succeed with it, & WIIFM (What's In It For Me?) why they must figure it out. A presentation for the Brady, Texas / McCulloch County Chamber of Commerce.
At Tourism Currents, we do online & in-person training in social media for tourism & hospitality. More at http://www.tourismcurrents.com/
C++ (pronounced "see plus plus") is a computer programming language based on C. It was created for writing programs for many different purposes. In the 1990s, C++ became one of the most used programming languages in the world.
The C++ programming language was developed by Bjarne Stroustrup at Bell Labs in the 1980s, and was originally named "C with classes". The language was planned as an improvement on the C programming language, adding features based on object-oriented programming. Step by step, a lot of advanced features were added to the language, like operator overloading, exception handling and templates.
Object-oriented programming (OOP) with Complete understanding modulesDurgesh Singh
Object-oriented programming (OOP) is the core ingredient of the .NET framework. OOP is so important that, before embarking on the road to .NET, you must understand its basic principles and terminology to write even a simple program. The fundamental idea behind OOP is to combine into a single unit both data and the methods that operate on that data; such units are called an object. All OOP languages provide mechanisms that help you implement the object-oriented model. They are encapsulation, inheritance, polymorphism and reusability. Let's now take a brief look at these concepts.
Errors detected in the Visual C++ 2012 librariesPVS-Studio
Static code analysis is one of the error detection methodologies. We are glad that this methodology is becoming more and more popular nowadays. Visual Studio which includes static analysis as one of its many features contributes to this process to a large extent. This feature is easy to try and start using regularly. When one understands one likes static code analysis, we are glad to offer a professional analyzer PVS-Studio for the languages C/C++/C++11.
Still Comparing "this" Pointer to Null?Andrey Karpov
This is a translation of an article written by Dmitry Meshcheryakov, an ABBYY employee and first published here: "ABBYY blog. Still Comparing "this" Pointer to Null?". Translation done and published with permission of the copyright holder.
Artificia Intellicence and XPath Extension FunctionsOctavian Nadolu
The purpose of this presentation is to provide an overview of how you can use AI from XSLT, XQuery, Schematron, or XML Refactoring operations, the potential benefits of using AI, and some of the challenges we face.
Quarkus Hidden and Forbidden ExtensionsMax Andersen
Quarkus has a vast extension ecosystem and is known for its subsonic and subatomic feature set. Some of these features are not as well known, and some extensions are less talked about, but that does not make them less interesting - quite the opposite.
Come join this talk to see some tips and tricks for using Quarkus and some of the lesser known features, extensions and development techniques.
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Crescat
Crescat is industry-trusted event management software, built by event professionals for event professionals. Founded in 2017, we have three key products tailored for the live event industry.
Crescat Event for concert promoters and event agencies. Crescat Venue for music venues, conference centers, wedding venues, concert halls and more. And Crescat Festival for festivals, conferences and complex events.
With a wide range of popular features such as event scheduling, shift management, volunteer and crew coordination, artist booking and much more, Crescat is designed for customisation and ease-of-use.
Over 125,000 events have been planned in Crescat and with hundreds of customers of all shapes and sizes, from boutique event agencies through to international concert promoters, Crescat is rigged for success. What's more, we highly value feedback from our users and we are constantly improving our software with updates, new features and improvements.
If you plan events, run a venue or produce festivals and you're looking for ways to make your life easier, then we have a solution for you. Try our software for free or schedule a no-obligation demo with one of our product specialists today at crescat.io
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Mind IT Systems
Healthcare providers often struggle with the complexities of chronic conditions and remote patient monitoring, as each patient requires personalized care and ongoing monitoring. Off-the-shelf solutions may not meet these diverse needs, leading to inefficiencies and gaps in care. It’s here, custom healthcare software offers a tailored solution, ensuring improved care and effectiveness.
Software Engineering, Software Consulting, Tech Lead, Spring Boot, Spring Cloud, Spring Core, Spring JDBC, Spring Transaction, Spring MVC, OpenShift Cloud Platform, Kafka, REST, SOAP, LLD & HLD.
AI Genie Review: World’s First Open AI WordPress Website CreatorGoogle
AI Genie Review: World’s First Open AI WordPress Website Creator
👉👉 Click Here To Get More Info 👇👇
https://sumonreview.com/ai-genie-review
AI Genie Review: Key Features
✅Creates Limitless Real-Time Unique Content, auto-publishing Posts, Pages & Images directly from Chat GPT & Open AI on WordPress in any Niche
✅First & Only Google Bard Approved Software That Publishes 100% Original, SEO Friendly Content using Open AI
✅Publish Automated Posts and Pages using AI Genie directly on Your website
✅50 DFY Websites Included Without Adding Any Images, Content Or Doing Anything Yourself
✅Integrated Chat GPT Bot gives Instant Answers on Your Website to Visitors
✅Just Enter the title, and your Content for Pages and Posts will be ready on your website
✅Automatically insert visually appealing images into posts based on keywords and titles.
✅Choose the temperature of the content and control its randomness.
✅Control the length of the content to be generated.
✅Never Worry About Paying Huge Money Monthly To Top Content Creation Platforms
✅100% Easy-to-Use, Newbie-Friendly Technology
✅30-Days Money-Back Guarantee
See My Other Reviews Article:
(1) TubeTrivia AI Review: https://sumonreview.com/tubetrivia-ai-review
(2) SocioWave Review: https://sumonreview.com/sociowave-review
(3) AI Partner & Profit Review: https://sumonreview.com/ai-partner-profit-review
(4) AI Ebook Suite Review: https://sumonreview.com/ai-ebook-suite-review
#AIGenieApp #AIGenieBonus #AIGenieBonuses #AIGenieDemo #AIGenieDownload #AIGenieLegit #AIGenieLiveDemo #AIGenieOTO #AIGeniePreview #AIGenieReview #AIGenieReviewandBonus #AIGenieScamorLegit #AIGenieSoftware #AIGenieUpgrades #AIGenieUpsells #HowDoesAlGenie #HowtoBuyAIGenie #HowtoMakeMoneywithAIGenie #MakeMoneyOnline #MakeMoneywithAIGenie
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteGoogle
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
👉👉 Click Here To Get More Info 👇👇
https://sumonreview.com/ai-pilot-review/
AI Pilot Review: Key Features
✅Deploy AI expert bots in Any Niche With Just A Click
✅With one keyword, generate complete funnels, websites, landing pages, and more.
✅More than 85 AI features are included in the AI pilot.
✅No setup or configuration; use your voice (like Siri) to do whatever you want.
✅You Can Use AI Pilot To Create your version of AI Pilot And Charge People For It…
✅ZERO Manual Work With AI Pilot. Never write, Design, Or Code Again.
✅ZERO Limits On Features Or Usages
✅Use Our AI-powered Traffic To Get Hundreds Of Customers
✅No Complicated Setup: Get Up And Running In 2 Minutes
✅99.99% Up-Time Guaranteed
✅30 Days Money-Back Guarantee
✅ZERO Upfront Cost
See My Other Reviews Article:
(1) TubeTrivia AI Review: https://sumonreview.com/tubetrivia-ai-review
(2) SocioWave Review: https://sumonreview.com/sociowave-review
(3) AI Partner & Profit Review: https://sumonreview.com/ai-partner-profit-review
(4) AI Ebook Suite Review: https://sumonreview.com/ai-ebook-suite-review
Enterprise Resource Planning System includes various modules that reduce any business's workload. Additionally, it organizes the workflows, which drives towards enhancing productivity. Here are a detailed explanation of the ERP modules. Going through the points will help you understand how the software is changing the work dynamics.
To know more details here: https://blogs.nyggs.com/nyggs/enterprise-resource-planning-erp-system-modules/
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Łukasz Chruściel
No one wants their application to drag like a car stuck in the slow lane! Yet it’s all too common to encounter bumpy, pothole-filled solutions that slow the speed of any application. Symfony apps are not an exception.
In this talk, I will take you for a spin around the performance racetrack. We’ll explore common pitfalls - those hidden potholes on your application that can cause unexpected slowdowns. Learn how to spot these performance bumps early, and more importantly, how to navigate around them to keep your application running at top speed.
We will focus in particular on tuning your engine at the application level, making the right adjustments to ensure that your system responds like a well-oiled, high-performance race car.
Launch Your Streaming Platforms in MinutesRoshan Dwivedi
The claim of launching a streaming platform in minutes might be a bit of an exaggeration, but there are services that can significantly streamline the process. Here's a breakdown:
Pros of Speedy Streaming Platform Launch Services:
No coding required: These services often use drag-and-drop interfaces or pre-built templates, eliminating the need for programming knowledge.
Faster setup: Compared to building from scratch, these platforms can get you up and running much quicker.
All-in-one solutions: Many services offer features like content management systems (CMS), video players, and monetization tools, reducing the need for multiple integrations.
Things to Consider:
Limited customization: These platforms may offer less flexibility in design and functionality compared to custom-built solutions.
Scalability: As your audience grows, you might need to upgrade to a more robust platform or encounter limitations with the "quick launch" option.
Features: Carefully evaluate which features are included and if they meet your specific needs (e.g., live streaming, subscription options).
Examples of Services for Launching Streaming Platforms:
Muvi [muvi com]
Uscreen [usencreen tv]
Alternatives to Consider:
Existing Streaming platforms: Platforms like YouTube or Twitch might be suitable for basic streaming needs, though monetization options might be limited.
Custom Development: While more time-consuming, custom development offers the most control and flexibility for your platform.
Overall, launching a streaming platform in minutes might not be entirely realistic, but these services can significantly speed up the process compared to building from scratch. Carefully consider your needs and budget when choosing the best option for you.
Do you want Software for your Business? Visit Deuglo
Deuglo has top Software Developers in India. They are experts in software development and help design and create custom Software solutions.
Deuglo follows seven steps methods for delivering their services to their customers. They called it the Software development life cycle process (SDLC).
Requirement — Collecting the Requirements is the first Phase in the SSLC process.
Feasibility Study — after completing the requirement process they move to the design phase.
Design — in this phase, they start designing the software.
Coding — when designing is completed, the developers start coding for the software.
Testing — in this phase when the coding of the software is done the testing team will start testing.
Installation — after completion of testing, the application opens to the live server and launches!
Maintenance — after completing the software development, customers start using the software.
OpenMetadata Community Meeting - 5th June 2024OpenMetadata
The OpenMetadata Community Meeting was held on June 5th, 2024. In this meeting, we discussed about the data quality capabilities that are integrated with the Incident Manager, providing a complete solution to handle your data observability needs. Watch the end-to-end demo of the data quality features.
* How to run your own data quality framework
* What is the performance impact of running data quality frameworks
* How to run the test cases in your own ETL pipelines
* How the Incident Manager is integrated
* Get notified with alerts when test cases fail
Watch the meeting recording here - https://www.youtube.com/watch?v=UbNOje0kf6E
E-commerce Application Development Company.pdfHornet Dynamics
Your business can reach new heights with our assistance as we design solutions that are specifically appropriate for your goals and vision. Our eCommerce application solutions can digitally coordinate all retail operations processes to meet the demands of the marketplace while maintaining business continuity.
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxrickgrimesss22
Discover the essential features to incorporate in your Winzo clone app to boost business growth, enhance user engagement, and drive revenue. Learn how to create a compelling gaming experience that stands out in the competitive market.
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
How to capture a variable in C# and not to shoot yourself in the foot
1. How to capture a variable in C# and not to
shoot yourself in the foot
Author: Ivan Kishchenko
Date: 27.01.2017
Back in 2005, with the release of C# 2.0 standard we got a possibility to pass a variable to the body of an
anonymous delegate by capturing it from the current context. In 2008 the C# 3.0 brought us lambdas,
user anonymous classes, LINQ requests and much more. Now it January, 2017 and the majority of C#
developers are looking forward to the release of the C# 7.0 standard that should provide us a bunch of
new useful features. However, there are still old features that need to be fixed. That's why there are
plenty of ways to shoot yourself in the foot. Today we are going to speak about one of them, and it is
related with quite an unobvious mechanism of variable capture in the body of anonymous functions in
C#.
Introduction
As I have stated above, we are going to discuss peculiarities of the mechanism of variable capture in the
body of anonymous functions in C#. I should warn in advance, that the article will contain a large
number of technical details, but I hope that both experienced and beginner programmers will find my
article interesting and simple to comprehend.
But enough talking. I'll give you simple example of the code, you should tell, what will be printed in the
console.
So, here we go.
void Foo()
{
var actions = new List<Action>();
for (int i = 0; i < 10; i++)
{
actions.Add(() => Console.WriteLine(i));
}
2. foreach(var a in actions)
{
a();
}
}
And now attention please, here is the answer. The console will print the number 10 ten times.
10
10
10
10
10
10
10
10
10
10
This article is for those who thought otherwise. Let's try to sort out, what are the reasons of such
behavior.
Why does it happen so?
Upon the declaration of an anonymous function (it can be an anonymous delegate or lambda) inside
your class, one more container class will be declared during the compilation, which contains fields for all
the captured variables and a method, containing a body of the anonymous function. The disassembled
structure of the program for the code fragment given above will be as follows:
In this case the Foo method in this fragment is declared inside the Program class. The compiler
generated a container class c__DisplayClass1_0 for the lambda () => Console.WriteLine(i), and inside of
the class-container it generated a field i, having a captured variable with the same name and the
method b__0, containing the body of the lambda.
Let's consider the disassembled IL code of the b__0 method (lambda body) with my comments:
3. .method assembly hidebysig instance void '<Foo>b__0'() cil managed
{
.maxstack 8
// Puts the current class item (equivalent to 'this')
// to the top of the stack.
// It is necessary for the access to
// the fields of the current class.
IL_0000: ldarg.0
// Puts the value of the 'i' field to the top of the stack
// of the current class instance
IL_0001: ldfld int32
TestSolution.Program/'<>c__DisplayClass1_0'::i
// Calls a method to output the string to the console.
// Passes values from the stack as arguments.
IL_0006: call void [mscorlib]System.Console::WriteLine(int32)
// Exits the method.
IL_000b: ret
}
All correct, that's exactly what we do inside lambda, no magic. Let's go on.
As we know, the int type (the full name is Int32) is a structure, which means that it passed by value, not
by reference.
The value of the i variable should be copied (according the logic) during the creation of the container
class instance. And if you answered my question in the beginning of the article incorrectly, then most
likely you expected that the container would be created right before the declaration of the lambda in
the code.
In reality, the i variable won't be created after the compilation in the Foo method at all. Instead of it, an
instance of the container class c__DisplayClass1_0 will get created, and its field will be initialized with 0
instead of the i variable. Moreover, in all the fragments where we used a local variable i, there will be a
field of a container class used.
4. The important point is that an instance of the container class is created before the loop, because its field
i will be used in the loop as an iterator.
As a result, we get one instance of the container class for all iterations of the for loop. Adding a new
lambda to the actions list upon every iteration, we actually add the same reference to the instance of
the container class created previously. As a result, when we traverse all the items of the actions list with
the foreach loop, they all have the same instance of the container class. And we take into account that
the for loop increments the value of an iterator after every iteration (even after the last one), then the
value of the i field inside the container class after the exit from the loop gets equal to 10 after executing
the for loop.
You can make sure of it by looking at the disassembled IL code of the Foo method (with my comments):
.method private hidebysig instance void Foo() cil managed
{
.maxstack 3
// -========== DECLARATION OF LOCAL VARIABLES ==========-
.locals init(
// A list of 'actions'.
[0] class [mscorlib]System.Collections.Generic.List'1
<class [mscorlib]System.Action> actions,
// A container class for the lambda.
[1] class TestSolution.Program/
'<>c__DisplayClass1_0' 'CS$<>8__locals0',
// A technical variable V_2 is necessary for temporary
// storing the results of the addition operation.
[2] int32 V_2,
// Technical variable V_3 is necessary for storing
// the enumerator of the 'actions' list during
// the iteration of the 'foreach' loop.
[3] valuetype
[mscorlib]System.Collections.Generic.List'1/Enumerator<class
5. [mscorlib]System.Action> V_3)
// -================= INITIALIZATION =================-
// An instance of the Actions list is created and assigned to the
// 'actions' variable.
IL_0000: newobj instance void class
[mscorlib]System.Collections.Generic.List'1<class
[mscorlib]System.Action>::.ctor()
IL_0005: stloc.0
// An instance of the container class is created
// and assigned to a corresponding local variable
IL_0006: newobj instance void
TestSolution.Program/'<>c__DisplayClass1_0'::.ctor()
IL_000b: stloc.1
// A reference of the container class is loaded to the stack.
IL_000c: ldloc.1
// Number 0 is loaded to the stack.
IL_000d: ldc.i4.0
// 0 is assigned to the 'i' field of the previous
// object on the stack (an instance of a container class).
IL_000e: stfld int32
TestSolution.Program/'<>c__DisplayClass1_0'::i
6. // -================= THE FOR LOOP =================-
// Jumps to the command IL_0037.
IL_0013: br.s IL_0037
// The references of the 'actions'
// list and an instance of the container class
// are loaded to the stack.
IL_0015: ldloc.0
IL_0016: ldloc.1
// The reference to the 'Foo' method of the container class
// is loaded to the stack.
IL_0017: ldftn instance void
TestSolution.Program/'<>c__DisplayClass1_0'::'<Foo>b__0'()
// An instance of the 'Action' class is created and the reference
// to the 'Foo' method of the container class is passed into it.
IL_001d: newobj instance void
[mscorlib]System.Action::.ctor(object, native int)
// The method 'Add' is called for the 'actions' list
// by adding an instance of the 'Action' class.
IL_0022: callvirt instance void class
[mscorlib]System.Collections.Generic.List'1<class
[mscorlib]System.Action>::Add(!0)
// The value of the 'i' field of the instance of a container class
// is loaded to the stack.
IL_0027: ldloc.1
7. IL_0028: ldfld int32
TestSolution.Program/'<>c__DisplayClass1_0'::i
// The value of the 'i' field is assigned
// to the technical variable 'V_2'.
IL_002d: stloc.2
// The reference to the instance of a container class and the value
// of a technical variable 'V_2' is loaded to the stack.
IL_002e: ldloc.1
IL_002f: ldloc.2
// 1 is loaded to the stack.
IL_0030: ldc.i4.1
// It adds two first values on the stack
// and assigns them to the third.
IL_0031: add
// The result of the addition is assigned to the 'i' field
// (in fact, it is an increment)
IL_0032: stfld int32
TestSolution.Program/'<>c__DisplayClass1_0'::i
// The value of the 'i' field of the container class instance
// is loaded to the stack.
IL_0037: ldloc.1
IL_0038: ldfld int32
TestSolution.Program/'<>c__DisplayClass1_0'::i
8. // 10 is loaded to the stack.
IL_003d: ldc.i4.s 10
// If the value of the 'i' field is less than 10,
// it jumps to the command IL_0015.
IL_003f: blt.s IL_0015
// -================= THE FOREACH LOOP =================-
//// The reference to the 'actions' list is loaded to the stack.
IL_0041: ldloc.0
// The technical variable V_3 is assigned with the result
// of the 'GetEnumerator' method of the 'actions' list.
IL_0042: callvirt instance valuetype
[mscorlib]System.Collections.Generic.List'1/Enumerator<!0> class
[mscorlib]System.Collections.Generic.List'1<class
[mscorlib]System.Action>::GetEnumerator()
IL_0047: stloc.3
// The initialization of the try block
// (the foreach loop is converted to
// the try-finally construct)
.try
{
// Jumps to the command IL_0056.
IL_0048: br.s IL_0056
// Calls get_Current method of the V_3 variable.
9. // The result is written to the stack.
// (A reference to the Action object in the current iteration).
IL_004a: ldloca.s V_3
IL_004c: call instance !0 valuetype
[mscorlib]System.Collections.Generic.List'1/Enumerator<class
[mscorlib]System.Action>::get_Current()
// Calls the Invoke method of the Action
// object in the current iteration
IL_0051: callvirt instance void
[mscorlib]System.Action::Invoke()
// Calls MoveNext method of the V_3 variable.
// The result is written to the stack.
IL_0056: ldloca.s V_3
IL_0058: call instance bool valuetype
[mscorlib]System.Collections.Generic.List'1/Enumerator<class
[mscorlib]System.Action>::MoveNext()
// If the result of the MoveNext method is not null,
// then it jumps to the IL_004a command.
IL_005d: brtrue.s IL_004a
// Finishes the try block execution and jumps to finally.
IL_005f: leave.s IL_006f
} // end .try
finally
{
// Calls the Dispose method of the V_3 variable.
IL_0061: ldloca.s V_3
10. IL_0063: constrained. Valuetype
[mscorlib]System.Collections.Generic.List'1/Enumerator<class
[mscorlib]System.Action>
IL_0069: callvirt instance void
[mscorlib]System.IDisposable::Dispose()
// Finishes the execution of the finally block.
IL_006e: endfinally
}
// Finishes the execution of the current method.
IL_006f: ret
}
Conclusion
The guys from Microsoft say that this is a feature, not a bug and that this behavior was made
intentionally, aiming to increase the performance of the programs. You will find more information by
this link. In reality it results in bugs and confusion of novice developers.
An interesting fact is that the foreach loop had the same behavior before the C# 5.0 standard. The
Microsoft was bombarded with complaints about nonintuitive behavior in the bug-tracker, but with the
release of the C# 5.0 standard this behavior was changed by declaring the iterator variable inside every
loop iteration, not before it on the compilation stage, but for all other constructions similar behavior
remained without any changes. More information can be found by the link in the Breaking Changes
section.
You may ask how to avoid such an error? Actually the answer is very simple. You need to keep track of
where and what variables you capture. Just remember that the container class will be created in that
place where you have declared your variable that you will capture. If the capture occurs in the body of
the loop, and the variable is declared outside it, then it's necessary to reassign it inside the body of the
loop to a new local variable. The correct version of the example given in the beginning can be as follows:
void Foo()
{
var actions = new List<Action>();
for (int i = 0; i < 10; i++)
{
11. var index = i; // <=
actions.Add(() => Console.WriteLine(index));
}
foreach(var a in actions)
{
a();
}
}
If you execute this code, the console will show the numbers from 0 to 9, as expected:
0
1
2
3
4
5
6
7
8
9
Looking at the IL code of the for loop from this example, we'll see that an instance of the container class
will be created upon every iteration of the loop. Thus, the actions list will contain references to various
instances with correct values of the iterators.
// -================= THE FOR LOOP =================-
// Jumps to the command IL_002d.
IL_0008: br.s IL_002d
// Creates an instance of a container class
// and loads the reference to the stack.
IL_000a: newobj instance void
TestSolution.Program/'<>c__DisplayClass1_0'::.ctor()
12. IL_000f: stloc.2
IL_0010: ldloc.2
// Assigns the 'index' field in the container class
// with a value 'i'.
IL_0011: ldloc.1
IL_0012: stfld int32
TestSolution.Program/'<>c__DisplayClass1_0'::index
// Creates an instance of the 'Action' class with a reference to
// the method of a container class and add it to the 'actions' list.
IL_0017: ldloc.0
IL_0018: ldloc.2
IL_0019: ldftn instance void
TestSolution.Program/'<>c__DisplayClass1_0'::'<Foo>b__0'()
IL_001f: newobj instance void
[mscorlib]System.Action::.ctor(object, native int)
IL_0024: callvirt instance void class
[mscorlib]System.Collections.Generic.List'1<class
[mscorlib]System.Action>::Add(!0)
// Performs the increment to the 'i' variable
IL_0029: ldloc.1
IL_002a: ldc.i4.1
IL_002b: add
IL_002c: stloc.1
// Loads the value of the 'i' variable to the stack
13. // This time it is not in the container class
IL_002d: ldloc.1
// Compares the value of the variable 'i' with 10.
// If 'i < 10', then jumps to the command IL_000a.
IL_002e: ldc.i4.s 10
IL_0030: blt.s IL_000a
Finally, let me remind you that we are all human beings and we all make errors, that's why it would be
illogical, and as a rule long and resource-intensive to hope only for the human factor when searching for
bugs and typos. So, it's always a good idea to use technical solutions to detect errors in the code. The
machine doesn't get tired and does the work much quicker.
Quite recently, we as a team of PVS-Studio static code analyzer developers have created a diagnostic
rule that is aimed at detecting incorrect capture of the variables and anonymous functions inside the
loops. In my turn I suggest checking your code with our analyzer and see if it can detect bugs in your
code.
At this point, I'm finishing my article, I wish you clean code bugless programs.