• Blog
  • Info Support
  • Career
  • Training
  • International Group
  • Info Support
  • Blog
  • Career
  • Training
  • International Group
  • Search
logo InfoSupport
  • Latest blogs
  • Popular blogs
  • Experts
      • All
      • Bloggers
      • Speakers
  • Meet us
  • About us
    • nl
    • en
    • .NET
    • 3D printing
    • Advanced Analytics
    • Agile
    • Akka
    • Alexa
    • Algorithms
    • Api's
    • Architectuur
    • Artificial Intelligence
    • ATDD
    • Augmented Reality
    • AWS
    • Azure
    • Big Data
    • Blockchain
    • Business Intelligence
    • Chatbots
    • Cloud
    • Code Combat
    • Cognitive Services
    • Communicatie
    • Containers
    • Continuous Delivery
    • CQRS
    • Cyber Security
    • Dapr
    • Data
    • Data & Analystics
    • Data Science
    • Data Warehousing
    • Databricks
    • DataOps
    • Developers life
    • DevOps
    • Digital Days
    • Digital Twin
    • Docker
    • eHealth
    • Enterprise Architecture
    • Event Sourcing
    • Hacking
    • Infrastructure & Hosting
    • Innovatie
    • Integration
    • Internet of Things
    • Java
    • Machine Learning
    • Microservices
    • Microsoft
    • Microsoft Bot Framework
    • Microsoft Data Platform
    • Mobile Development
    • Mutation Testing
    • Open source
    • Pepper
    • Power BI
    • Privacy & Ethiek
    • Python
    • Quality Assistance & Test
    • Quality Assurance & Test
    • Requirements Management
    • Scala
    • Scratch
    • Security
    • SharePoint
    • Software Architecture
    • Software development
    • Software Factory
    • SQL Server
    • SSL
    • Start-up
    • Startup thinking
    • Stryker
    • Test Quality
    • Testing
    • TLS
    • TypeScript
    • Various
    • Web Development
    • Web-scale IT
    • Xamarin
    • All
    • Bloggers
    • Speakers
Home » Changed behavior outervariables in C#
  • Changed behavior outervariables in C#

    • By Marcel de Vries
    • .NET 10 years ago
    • .NET 0 comments
    • .NET .NET
    Changed behavior outervariables in C#

    *Moved to: http://fluentbytes.com/changed-behavior-outervariables-in-c/

    Last month I did one of my talks called Introduction to the LINQ programming model at the VSLive! conference in Orlando FL. While on stage I was all of a sudden caught of guard when I showed a common problem C# programmers run into when working with LINQ.

    The example I always show is the following loop where we have a lambda expression capturing the loop variable

    char[] vowels = { 'a', 'e', 'o', 'i', 'u' };
    query = "not what you might expect";
    
    foreach (var vowel in vowels)
    {
       query = query.Where(character => character != vowel);
    }
    
    printResults(query);
    

    Here most people expect the result of the printed string to be:
    “nt wht y mght xpct” but it will print “not what yo might expect”

    The logical explanation for this is that the lambda expression captures the reference to the variable location vowel and that location contains the last value of the loop when you print the results after the loop.

    I have demonstrated this many many times, but all of a sudden the string printed:
    “nt wht y mght xpct”

    I took me some time to figure out what has caused my demo to all of a sudden change in behavior, but the explanation is quite simple. This was the first time I used Visual Studio 2012 for this demo and my project was converted to target .NET 4.5.

    Apparently Microsoft made the decision that they wanted to fix this common misconception and make the compiler more smart about the fact that the for loop introduces only a local variable to the loop and it can be considered as a local variable and therefore capture the value in stead of the reference!

    I don’t expect this to cause a lot of trouble in existing programs. I can’t think of any reason why one would like to make useful use of the previous behavior. You do  need to be aware of the fact that this change is only made for foreach loops. So if you program a for loop you will still get the previous behavior where the lambda expression captures the outervariable of the loop.

    Consider the following code:

    var values = new List<int>() { 100, 110, 120 };
    var funcs = new List<Func<int>>();
    foreach (var v in values)
        funcs.Add(() => v);
    foreach (var f in funcs)
        Console.WriteLine(f());
    

    This will yield different results in .NET 4.5 then in previous versions.

    Previous versions will yield the result 120, 120, 120 and 4.5 and above will yield 100, 110, 120

    Now consider the following code:

    funcs = new List<Func<int>>();
    
    for (var v=100; v < 120; v+=10)
        funcs.Add(() => v);
    
    foreach (var f in funcs)
        Console.WriteLine(f());
    

    What will the result of this code be when compiled targeting .NET 4.5?

    Yep, it will result in 120, 120, 120

    Microsoft has made the decision that with the for loop the variable of the loop is influenced by the += operator and therefore is obviously not local to the inner loop and therefore the behavior remains the same for the future.

    You can find more details on this on Erik Lipperts blog over here.

    Hope this shines some light on the reason of my demo failing at VS Live :-),

    Marcel

    Follow my new blog on http://fluentbytes.com

    Share this

Marcel de Vries

View profile

Related IT training

Go to training website

Related Consultancy solutions

Go to infosupport.com

Related blogs

  • Building a custom Kubernetes operator in C#

    Building a custom Kubernetes operator in C# Willem Meints - 2 months ago

  • Transform SpecFlow Table Column

    Transform SpecFlow Table Column Ronald Bosma - 5 months ago

  • Building a passwordless login flow with WebAuthn and th…

    Building a passwordless login flow with WebAuthn and th… Willem Meints - 7 months ago

Data Discovery Channel

  • Explainable AI - Break open the blackbox

  • Toekomstvaste microservice data architecturen

  • Modern Data Platform

Nieuwsbrief

* verplichte velden

Contact

  • Head office NL
  • Kruisboog 42
  • 3905 TG Veenendaal
  • T +31 318 552020
  • Call
  • Mail
  • Directions
  • Head office BE
  • Generaal De Wittelaan 17
  • bus 30 2800 Mechelen
  • T +32 15 286370
  • Call
  • Mail
  • Directions

Follow us

  • Twitter
  • Facebook
  • Linkedin
  • Youtube

Newsletter

Sign in

Extra

  • Media Library
  • Disclaimer
  • Algemene voorwaarden
  • ISHBS Webmail
  • Extranet
Beheer cookie toestemming
Deze website maakt gebruik van Functionele en Analytische cookies voor website optimalisatie en statistieken.
Functioneel Always active
De technische opslag of toegang is strikt noodzakelijk voor het legitieme doel het gebruik mogelijk te maken van een specifieke dienst waarom de abonnee of gebruiker uitdrukkelijk heeft gevraagd, of met als enig doel de uitvoering van de transmissie van een communicatie over een elektronisch communicatienetwerk.
Voorkeuren
De technische opslag of toegang is noodzakelijk voor het legitieme doel voorkeuren op te slaan die niet door de abonnee of gebruiker zijn aangevraagd.
Statistieken
De technische opslag of toegang die uitsluitend voor statistische doeleinden wordt gebruikt. De technische opslag of toegang die uitsluitend wordt gebruikt voor anonieme statistische doeleinden. Zonder dagvaarding, vrijwillige naleving door uw Internet Service Provider, of aanvullende gegevens van een derde partij, kan informatie die alleen voor dit doel wordt opgeslagen of opgehaald gewoonlijk niet worden gebruikt om je te identificeren.
Marketing
De technische opslag of toegang is nodig om gebruikersprofielen op te stellen voor het verzenden van reclame, of om de gebruiker op een website of over verschillende websites te volgen voor soortgelijke marketingdoeleinden.
Manage options Manage services Manage vendors Read more about these purposes
Voorkeuren
{title} {title} {title}