 Hello. We're back at the.NET Comp. So welcome to my talk. It's the latest productivity updates in Visual Studio 2017, specifically for version 15.8. I'm Kendra Havens. I'm a program manager on.NET in Visual Studio. So if you haven't watched one of our productivity talks before, we always try to cram in the tips and tricks and just the little things that make coding in Visual Studio so much easier. So we have a lot of awesome updates to share. Again, a lot of these that I'll be going through, we're all customer asks. So if you filed a feedback on developer community or engaged with us on our GitHub repositories, thank you so much. The community being a part of this development is huge. Okay. Let's dive in. So this is a general overview. First, I'll talk about all of the performance improvements that we've packed into all of the Visual Studio version like 15.0 releases and also specifically what we got into 15.8. After that, I will basically do one whole demo of refactorings and code fixes, source link debugging, the different code cleanup options that we've recently added, as well as editor config tooling that we have, and IntelliCode. If you don't know what some of these are, you are in for such a big treat. I'm so excited. Okay. So first off, performance. So specifically in Visual Studio 2017 version 15.8, the very latest stuff, we are still focusing so much on solution load. Performance is always one of the top things that customers bring up, and solution load is also right at the top within the performance category. So just in general, across this release cycle, solution load is already 25 percent faster in Visual Studio 2017 than it is in 2015. I actually think that's a super conservative estimate, so I'd really love to know what you all experience in the wild. If you ever wanted to do a blog post about how much better it is working for your solution, I'd really love to see it. Something we also focused on improving performance for is branch switching. That can really interrupt your development flow if you're not being able to switch in between branches really quickly, so we are focusing on that. We also focused on unloading and reloading C-Sharp and Visual Basic projects, making that a lot faster, as well as test execution. Now test execution I'm extra excited about because that's what my team specifically works on every single day, besides just the general productivity category. Listen in. For large test projects, if you run a few tests within them, that test execution is where we've seen the most improvement. So in our labs, for an MS test project with many different test projects with over 10,000 tests, when you're only running a single test, it can execute 82 percent faster. That's huge. We're so excited about that. So I can't wait to show that later. Also, I just want to call out earlier across the versions in general 15 updates, much better solution load during the whole time we've made incremental improvements as well as much better test discovery. I can't talk about performance with actually also having a video all on test discovery. So I have a side-by-side comparison video. You will see solution load just a little bit in the beginning. It happened so fast because I didn't use a big enough solution for this. That it's hard to see the difference in the improvement across these updates, but test discovery is huge. So on the left, we have Visual Studio 2017 update 15.5, and on the right, we have update 15.8. Now they're both loading a 10,000 tests project, and you can see on the right, it's already finished. So that was 10,000 tests discovered in less than five seconds. On the left side, we previously needed to build in order to discover tests because we discovered tests by assemblies back then. On the right, we introduced source-based discovery. So I added a test. It was automatically discovered because it's just running over my source. I didn't need to build, and then I could execute that really quickly. On the left, it looks like we're still not quite up to... Oh, okay, so it looks like it's discovered 10,000 tests, but when I right-click, I can't quite execute it yet because it's still finding all of the information and loading it into the test explorer, and now it's discovered. So that took about 29 seconds. Compare that to what it is now at 4.75. Huge improvement. Okay. So moving on from performance, let's dive right into productivity tips and tricks. Now, I want to give you guys sort of a... Let's see what you call it. Warning, the next slide is really text-heavy. Ah, okay. This is because we have packed in so many features into even minor visual studio releases. So here on the right, I've kind of sectioned off everything I'm about to dive into for 15.8. This will include new keyboard profiles for VS Code and Resharper, refactorings, but all of those you access through control dot and their code fixes, we've got for loop to for each, invert if, converting to a ternary conditional. You can have a code fix to add a parameter from the call site, as well as removing extra parentheses, which I'm gonna use all the time. We also have finally multi-cursor mode, officially in 15.8. You don't need an extra extension. You don't need to turn on a feature flag. It's just there by default. It is control alt click. So excited to show that to you guys. We also added improved our navigation a bit. So the control T navigation or our go to all, we also added a recent files, a shortcut that I'll show you soon. And we also have a navigation keyboard shortcut for going to the closing block. Then in my demo, I'll dive into the code cleanup, one click code cleanup, controlled KD. We're really excited to share more about that. And the code cleanup configuration and tools options that we've added. I'll also cover and telecode, which is really exciting. Okay, throughout this demo, I'll also be wanting to call out just the major improvements that we've made previously across Visual Studio versions, because there's so many. I'll definitely go over source link debugging. Oops, I think it did come out in 15.8, but it is compatible back to 15.7, which is very exciting. So I'll kind of be covering, navigate to decompiled assemblies, go to definition, all of the test explorer improvements, just that we've made in earlier versions, just so people know they're hearing the big stuff. Okay, did I call out everything? Yeah, that looks good. Okay, let's dive into the demo. Escape PowerPoint gross. Okay, so I'm generally going to be opening our smart hotel 360 app. This app you've probably seen if you watched any of our build demos, what were the most recent things? If you've gone to any of the Visual Studio Live, et cetera, you might have seen our smart hotel 360. It's just a general web app that runs on an Azure app service that allows hotel guests to book rooms or book services through our website. So I'll go ahead and open that. And if you will, keep your eye on the test explorer because I'll never get over how excited I am about source-based discovery. So yeah, loaded and boom, 5,000 tests discovered in a matter of seconds. So nice. So as you can see, I can expand the test explorer to see a hierarchy view. That was a huge customer ask. It's organized by project namespace in class. I think we got that in first in 15.6, but still major feature people are excited about. Another major one, since we're already inside of the test explorer, is actually making more responsive test runs. So as I run this, you can see test pending to execute, get this clock icon, and tests that are currently executing get a progress ring. This is so key when you have a really long test run and you're trying to figure out what is holding up your test run and what is taking so long. And you have a suspicion. You're like, okay, I think this test is the culprit. You're actually immediately getting feedback on that in the test explorer. So we're really excited to sort of be able to easily identify whatever laggy tests that you might be seeing. Okay, before I dive into my code, I actually wanted to show you our new key bindings. So you can easily get there by typing keyboard and quick launch or just going to tools options. It's under environment and keyboard. And I'm definitely going to use the default for this demo because that's what I'm really comfortable in. But we now have an option to use resharper key bindings as well as visual studio code. So it'll make it so much easier if you find yourself switching between IDEs and which is great because we just want to make you more productive. Okay. And before I dive into my whole demo code flow, I actually want to, oh right, I didn't show off more of test discovery. If I uncomment a test, it'll boom, automatically appears in the test explorer. I mean, yeah, I'll never get tired of doing that. So it didn't require a build for it actually to appear. Super, super helpful. Okay, so with the first code fix that I want to show off, it is actually caused by a merge conflict. So I'll go ahead and cause a merge conflict really quick. So I'll go up to merge in the team explorer and I'll select to merge master with this add test branch that I already had. Oh yeah, and I'll go ahead and save. So merge conflict appears because on my other branch, I had already tried to add a similar method at the same place. You can see the code fixes appearing already. So you can kinda give us some more room here. So I can see when I hit control dot, which opens up the light bulb that I get, I can choose what branch I would like to take in order to resolve the merge conflict and I can even choose both and it'll just erase the comments that the merge conflict inserted. So I'll go ahead and take the head. There we go. Okay, so now let's focus in on, so that is a 15.8 feature and that was actually submitted by the community which was very, very cool. So thank you contributors. All right, so I want to go ahead and investigate one of my failing tests right here. And actually, since I want more room to work with this, one minute. Oh, I just wanted to check something really quick. Do, do, do, do, do, do, do. Oh yeah. Oh, it's not loading. Okay, there we go. Okay, now I'll feel better, sorry. Okay, so let's go ahead and check what's happening with this null check. Why is it causing it, why is it failing? So since I'll be working a lot with tests and trying to get it to pass again, I'm gonna go ahead and start live unit testing. Now, I'm sure a lot of people have heard about it for now but just to make sure everyone's on the same page, live unit testing can listen to your code changes as you type and run any tests that are affected by those code changes in the background as you're developing. And it will give feedback in the margin on that test. Whether, for whether, so you know whether or not it passed or failed. So if you guys remember, I had 5,000 tests in this project. I know some of them are just perf tests or regression tests or integration tests. They're not unit tests. So I don't actually want to include them in live unit testing because they're less interesting at this point. Something we added to live unit testing is the ability to exclude a large test project. So now I know that the tests that are running over my code are only the unit tests and not those integration tests that I didn't want running. So I can actually get feedback in, the feedback that I want right in the margin. So I'll go ahead and use control click to investigate my text housekeeping method. So this is generally, this is part of my go green request. You could see that the title of the test was my go green null test was failing. So this is if a customer at our hotel wanted to go green for a while and opt out of all the new towels and like getting new sheets every single day because nobody needs that much. So this checks. So as part of that function, they can also text housekeeping and we can insert a message for them. But it looks like the go green null test is throwing an exception. So I'm getting a null reference. So I'm gonna go ahead and debug this. And just wanted to really quick call out that we have an awesome exception helper that pops up. Now when you're debugging in Visual Studio 2017, you can actually manage the options of why it will appear. So I'm getting my message is null and it's no reference exception. So I'll go ahead and stop debugging and add a null check. One of the many code fixes and refactorings, of course, is our null check. You might have seen it before, but here's what's brand new in 15.8. When I drag this down and I make it a part of my if statements that's checking whether or not the customer has had housekeeping within the past seven days, I get an interesting little sort of prompt here. I can tell that my parentheses are actually grayed out. So in 15.8, we added remove unnecessary parentheses. And now that I see that it's there, I'm actually noticing I get this everywhere in my code. I guess I was always the kid in the English classroom that added way too many comments to their sentence. So I guess when I learned to code, I started doing the same thing with parentheses. So luckily, we have a Rosalind analyzer to take care of that for you. So something else you might have noticed when I was opening my code fixer, this area, when I hit control click inside of an if statement, it actually offers for me to invert the if else statement. So I can go ahead and hit that. And that's just a really kind of clever, helpful thing that helps you refactor code really easily. Something I also wanted to call out that as soon as I placed in these nil checks, I now have passing tests. So live unit testing was already in the background rerunning my test for me. So I'll go ahead and do the, Oh, invert nil check up here. But I do really hate when return false is before return true. I don't know why, that's just me. So I think I'll go ahead and go back. There we go. So there we go. So we got a few other options within when we hit control dot and we had clicked inside the if statement. One of these is converting it to a conditional expression. So that was a very simple, so this converts a very simple if else statement that returns to a false into a ternary expression. And then of course I'm getting prompted to also just use an expression body for this method. Something I wanna call out is that if I had a more complicated if else statement that maybe had an if statement nesting inside of it and it wasn't always returning true there. Oops, there we go. If I try to trigger this code fix again, ooh, I actually no longer get the prompt to transform it into a ternary condition. So it kind of only suggests it when it's a simple fix that you can easily do on your code and doesn't when your code is a bit more interesting. So I'll go ahead and convert it to a ternary expression and then go ahead and make that a expression body. Ah, feels really good. Okay, just got my demo cheat sheet to make sure I don't skip any of these because I'm not going too fast. Okay, so when we're texting housekeeping, this client is sending us a message and I actually wrote an Azure Cognitive Service that could run over the guest comments that guests are leaving and actually give a sentiment score for how they're doing. So within this, I'm actually iterating through this little sentiment batch result item in order to calculate the score in text housekeeping. One of the refactoring we added is the ability to convert from four to four each so I can rename my variable that I'm using to iterate it and I can also convert back from a for loop to a for each. Just a really simple code refactoring that is all about sort of someone's taste and how easy it is for them to read code. We now have write in the editor. So let's see if I, yeah, okay, I'm doing good. So one of the other refactoring that's right in this area is converting to from link to for each. So we're really excited to show this off because it was definitely a top customer request. So if I go ahead and, ooh, select, oh sorry, Shift Alt, select my link statement. There we go. I can trigger the code fix so I can convert my link query to for each. And I mean, not that I've ever had issues reading link but really if there's anyone new on your team who isn't as familiar with the latest C-sharp features it's really nice to have this code fix then. So we don't yet have the code fix to convert for each back to a link but we really hope, I hope that I can demo that around that 16 previews. Maybe connect timeframe, maybe ignite timeframe. It'd definitely be in preview there but we understand that that is definitely a high interest code fix to get in. Okay. So going back up to this calculate chocolate method I am actually only texting housekeeping to leave more chocolates if the sentiment score is underneath 0.5. So it analyzes the guest comment and then it gives a score from zero to one. It's just a pretty easy to use Azure Cognitive Service. So what I'm not doing is actually calculating how many chocolates that we should leave based on how negative their score was. So what if I went ahead and added that here? So what if I did something like 10 minus, uh oh, I'm gonna get warnings for using way too many parentheses again. See, told you guys. So what if I had something more like this? Let's go ahead and remove that extra parentheses and you actually see I had another code fix pop up there. I can also add the extra parentheses to make the meeting more clear because, hey, order of operations is pretty smart. There we go. We'll have that all in one line because it's easier to read. So in this case, if the customer had a sentiment of like 0.4, it would get down here and it times it by 10 so it'd be four and then 10 minus four is six. So I would text housekeeping to leave six extra chocolates on the pillow, right? But the text housekeeping method doesn't actually have that parameter. So this is our code fix for adding the parameter from the call site. So now that I did that, you see I don't get an error and if I actually navigate to text housekeeping which control click, you can see that it added this double. So if I actually went to the error list, you'd see I call this method in a lot of other places so I should definitely add a default value and that takes care of the other issues I was having. So I definitely want to include this in housekeeping in my message so I might as well just be using an interpolated string. That was such an easy fix to do. Feels so good. Man, interpolated strings get on board everyone. Okay, so something you might have noticed. Let's see if I got everything. Yep, looks good. Okay, so something you might have noticed when I was working in the calculate chocolate method was I didn't actually have any live unit testing test running. That's because the test that I have for this isn't actually included in live unit testing and I'll show you why. So I want to navigate to my chocolate sentiment test. So I should use control T for that, right? And I could use the regular camel case searching which is pretty fantastic. Or let's say it's a Monday and I don't actually remember the camel case or even like my test name, I can also choose, but I do know I was working in it recently, I can also just type R now. So it'd be control T R and that will bring up all of the files I've most recently been using. You can also click this little recent files clock icon in order to open this up. So control T navigation has always had, you've been able to type an F for specifically searching for files, a T for types and M for members. Now we have R, recent files. So pretty wonderful. I'll go over to my chocolate sentiment. So test, so this test has a skip when live unit testing category because as you remember, this is actually calling an Azure cognitive service and I don't exactly want that running every single time that I make a code change, right? It's not that that would be too many interactions but I would not expect to get like 3,000 interactions in one coding session from the Azure cognitive service. So I probably just want to keep those in manual run. So this test is actually in a test file with several other projects that are included in live unit testing but since this has a skip category, I can avoid it. Okay, so this test is actually failing. So it looks like it actually doesn't have enough, let's see, so inputs, returning to grant a chocolate sentiment. So what I should do is put in some more guest comments that are more negative. So I can select these and hit control D to duplicate them. That's one of the newer code fixes as well. And then get ready for it, multi cursor. I can hit control ALT and click in multiple places in order to edit code in all of them. So I'll say, very bad, awful, means more chocolate, there we go. And as you notice, Azure cognitive service is pretty cool here. I'm actually entering in multiple different languages and then it's converting it into the sentiment score that I need. So that's just also a really helpful thing. So it looks like I added four more negative comments. Oh wait, let's see, I think I misspelled chocolate. Can I go ahead? Oh, it undoes all of them, that's right. Oh, but if I actually still have my cursor there, so I'll go ahead and spell it correctly. There we go. Okay, so I can use my code lens icon to rerun this test manually and it should pass. Running, running. There's the tiny running icon. I was talking too long. Oh, there we go, okay, it passed. Okay, so I wasn't super familiar with Azure cognitive services when I was first building out this app. One thing that was really, really helpful when building out my service for this, I needed to learn a few things about this NuGet reference that I'm using. And so I didn't know exactly what they expected to have like a multi-language input. I didn't know how we needed to read the guest comments as strings into the correct format in order to make like a language batch result. So I could use just my cursor to hover over it and get more info about what this method expects me to be inputting. But one thing that was super helpful was navigating to the decompiled source. So this is Navigate to Decompiled Assemblies. You do need to turn it on. It's not on by default. You can turn it on in the text editor. Whoops, that's not it. I thought it'd take me right there, text editor. There we go. So it's the text editor. I think it's C-sharp and advanced. So this is your Enable Navigate to Decompiled Sources and it is still in experimental. So we partnered with Isle Spy to use their decompiler in order to decompile a source. And usually you will see like a ULA agreement pop up to make sure that we're allowed to be decompiling one of your NuGet references. So make sure you pay attention to that. But I know this is Azure Cognitive Services. They're totally okay with me doing it. So if you focus back in here, you actually see more than just getting what order of strings I needed to read into this, language, ID, and then text. I also got that, oh, language. They're expecting a two-letter ISO representation. So like EN for English or ES for Spanish. That's really helpful to know what input they're expecting. So that's Navigate to Decompiled Sources. But what if the NuGet reference that I'm using is actually open source? That brings me to Source Link Debugging. So I'll go ahead and jump to a different test so I can show you Source Link Debugging. This is my airport shuttle request test. So I was sort of in the middle of implementing a function for my users that, so the guests of the hotel would be able to order an airport and get, or sorry, order a shuttle in order to get to the airport. In order to do this, I took a dependency on KC Ulin Hoot's Bus Helper's NuGet reference. So let me show you what Source Link Debugging can do. I can set a break point. And I'll go ahead and debug this test. So as soon as I step into this, since I know this NuGet reference has Source Link, I'm actually stepping in to the reference so I can see how someone else's NuGet reference is handling the inputs I give it as I step through it. If I hover over this little bushelpers.cs file at the top, I can see that this source is actually in my app local data sources, so, or data source server. So this is actually not a part of my source code, but since KC Ulin Hoot, the package maintainer, was able to publish it with .NET Core SDK 2.1.3 or later and all the maintainers need to do is change a few things within the CS project in order to enable this. I'm actually able to step through her source. So, something you also see is that this also has a commit ID within it. So you actually know the particular commit that the publisher used to publish their NuGet package. So when you're browsing through the source online, you will know what you're actually debugging through because you can still compare commits. Very cool. So I'm sure a couple more things I wanna call out about debugging is we've added this run to click debugging. Super easy to use if your hand is already on the mouse. Something else that we're extremely excited to talk about more is this little tiny arrow in the top. So this is step back debugging. And as soon as I hit this, I actually go into an historical debugging mode. So this is not recompiling my code, but I can step back and see what the local variables were and their values when I had compiled that step. This is super helpful for if you ever realize you stepped just a little bit too far and you don't want to recompile that line of code by clicking run to click above your method or above your stepper where you currently are, you can just step back and see what those variables were. So I could click return to live debugging or if I step all the way forward again, I will actually enter back into just the regular debugging mode. So sort of back to live debugging. So we're really excited to show off that historical debugging feature. Okay, so that was source link debugging as well as the rent to click and step back debugging, all of which we're really excited about. The next major thing that I want to talk about is in telecode. So we've always known generally good programming practices to have and what we should be recommending to users but it's about time machine started teaching us instead. So in telecode is an extension right now in Visual Studio so it's not there by default, you gotta go grab it. I would highly recommend doing so. In telecode is an extension that offers better dot completion, better overloads and a few other things. So what it is is a machine algorithm that ran over 2,000 dot net repositories that are in the open source out on GitHub and figured out what the best coding practices and coding styles people are using in certain situations. So let me show you it in action. So here I'm calling dot on this little first shuttle string. So the most common overloads or properties or sorry methods that people would use on a string are now listed up at the top before without in telecode we just sort of have the static alphabetical list. That's not getting people anywhere fast. So it actually is saying that the most common property that people use in a dot completion would be length on string. So in telecode is super great in that if I change this to expect a string array instead of just a bar and I type dot completion again, I actually now get split at the top. So that's what it expects. So if I went ahead and did that and then typed a parentheses in order to trigger my overload suggestions, you can see in telecode again. So which is helpful because split actually has 10 overloads and it can tell me what is the most common overload used for this method. So it's super helpful. So even if I change this back to bar, now I mentioned that in telecode can also learn what context you're operating in. So I just called split right above this method. It now thinks as soon as someone calls split, it is more likely that they call trim. So you'll notice if this had no context around it, it still would have been dot length up at the top. Just a really cool feature. And then if I do my dot completion a third time, it now knows that I'm actually just repeating myself. So it is offering split again because that's what I will more likely want to use in this context. So this is super helpful. This is a date time function. So if I do dot completion on that, similar sort of recommendations are at the top. So it's really popular unlike commonly used types. So assert is definitely one of those. So it'll have top suggestions for assert as well as like top overloads for the most common things used in assert. The last thing I want to call out about in telecode is let's take for example, Casey Ulinhood's best helper Nuke reference. So I don't actually have this class library was not one of the libraries that in telecode trained on properly, probably or it's just not used as commonly. So you won't see in telecode suggestions there, which makes a lot of sense. Okay, so that is in telecode. So the last thing, well, one of the other code fixes that I wanna show you, or sorry, this is a navigation shortcut is control out alt up arrow. That is jumping to your enclosing block. So it'll only work for jumping from the bottom to the top. So if I put my cursor inside of my class and hit control alt up arrow, I will jump to the top of my class. So just another nice little navigation feature that you find yourself using a lot. So, what is the code style and spacing happening over here? This does not look good. Don't worry, we'll get rid of this in a second. One thing that we are really excited to introduce is the one click code cleanup. So that is control KD. Feel so much better with my spacing, but I'm noticing it didn't actually apply the var rule, even though I'm being prompted with a code suggestion for it to apply. So, in order to change this, that's actually because we put the var code style rule as unchecked by default. And I'll show you what I mean. So I can go to my cleanup options and that is in text editor, C sharp code style formatting general, or if you forget that line of things, just hit control Q, it'll put your cursor in quick launch and you can type in cleanup. And it'll bring you right where you need to be. So this apply implicit explicit type preferences is now unchecked by default. We realize that would probably be a more gentle interaction to code cleanup. We don't need people breaking each other into jail with that one when you're trying to just apply code styles with your team. So I'll hit control KD again and now I have explicit types. Okay, so I also wanted to mention really click that when I was in the options up there, you can also set a lot of your code style preferences in the IDE from Visual Studio. So it's interesting, I actually have preferring explicit type but I'm not actually offering a suggestion only a refactoring, but you're still seeing that I'm getting a, well, I was getting a suggestion in my actual code file. This is because I have an editor config. So editor configs can overrule the code style rules that you have set through the Visual Studio UI and I wish that I could demo the ability to export the code style rules that you've already set through Visual Studio into an editor config file format. That's something we're definitely working on we hear you. Hopefully maybe that'll be like a Dev 16 preview, I'm sorry, Visual Studio 2019 preview kind of thing that we can show later, but not yet, but we're working on it. So if you, a lot of you may have heard about editor config before, it's in absolutely like applauding the community kind of thing. Editor config existed before like apart from .NET and we adopted it because it was an awesome sort of code style and universal formatting guide that people could use across IDEs and languages. So we adopted it and worked with that community, awesome stuff, and created our own .NET code style. So this is what you see in this .editor config that I have in my solution, but you realize that, yeah, these can be, these might be kind of tedious to set yourself. So what I actually wanna show you is where editor config and IntelliCode intersect. So I'll actually go ahead and save this file. Okay, so over in my solution explorer, like let's say that I wanted to, I really liked all of the coding style in my public web.test project. If I wanted an editor config that exactly matches the code style that I'm already following in the project, IntelliCode can help me make that. So what I need to do is right click add a new item and search for editor config. Ooh, config. So we have a default editor config and a .NET editor config, but if you have the IntelliCode extension installed on your machine, you can actually create an IntelliCode inferred editor config. Now another awesome thing about editor config is that it can nest and it's directory based. So this editor config will still inherit from the root that I have on my solution level, but any rules that it has specifically set, it will overrule, but only within my public web.test context. So I can have different code style rules in my test project versus my project code. So if I went ahead and looked at the comments here, I can actually say that this file was initially inferred by Visual Studio and IntelliCode from my test project. So that is super helpful. And it also has the date listed in there, so I know when it was actually inferred. So if I scroll down to where I am setting my bar rules and I go ahead and change my using bar for built-in types to true and go back to my guess or test test, request test, you will now see it rerun over this test or maybe not or maybe I'll switch this again and save it and then go back. There we go. Okay, maybe it just needed a little bit more time. So now I am getting the code fix to apply var instead of the explicit type and I could do this in my whole document or I could just hit control KD again because I know it's now being picked up as under those code style rules. Okay, so that is IntelliCode combined with editor config. Now see, you thought I was making a statement about using var or explicit types but now we're just back to using var. So I am completely neutral in that argument. We're not starting a year. This is a war-free zone. Okay, so that was a lot of content. Let's do a quick recap back on the slides. So, oh, we'll go here. Okay, so I showed off new keyboard profiles, several refactorings for loop before each invert if, turnery conditional, all of that, I won't read through all of them again. Something you might have noticed with all of these features being added to every single version, even minor versions of Visual Studio is that there's a lot of them first off and we're iterating very fast and I can't stress this enough. A lot of this is due to our really big decision of re-architecting the Roslyn compiler that we first shipped back in Visual Studio 2015. So Roslyn was our C-sharp and Visual Basic compiler that was re-architected to be an extendable API that was completely focused on being open source and more of a platform for a community to plug into. The community had an awesome response to that. I know the merge conflict code fix is definitely contributed by the community. I think there were a few more in there, but we just had a really incredible response there. So, part of extending Roslyn is being able to create your own Roslyn analyzers. So I just want to take you through really quick what that looks like. I think it's so important that people sort of wrap their heads around what exactly creating your own Roslyn analyzer means. So if I went ahead and created an analyzer code fix provider, I'm only getting these errors because it hasn't restored. I can actually launch an analyzer project and in doing so, it launches another version of Visual Studio. I'm not sure if you all have seen this before, but it's very meta. So you're running Visual Studio from Visual Studio. So sometimes it takes a little bit longer to start up, but this version of Visual Studio is being launched by this one. So if I went ahead and opened my console project, I can actually see our default analyzer template running over it. And sure, it takes a little bit of extra time for Visual Studio to also launch Visual Studio, but I feel like the metaphor is strong when I do go through it. Preparing solution, there we go. Okay, so here I have just a class named Kendra and our default analyzer, just when you file new project Roslyn analyzer, is making a code fix that changes your class name to all caps. So it's makeup or case. So I can actually set a break point within there. I'll probably need to maybe set it down there and open up my other version, there we go. And now when I hit the control dot to open my code fix, it actually triggered a break in my analyzer project in Visual Studio. So that's sort of what analyzer development implies. It's really fun to do and the community has had such an incredible response to using it. Actually, I think I'll go ahead and show you one of them. If I went ahead and opened an Xunit project, you can see what Roslyn analyzers the Xunit community has already made using the Roslyn APIs and they're very cool. So you can see in my solution explorer that I actually have an Xunit project rule set. That's because I went ahead and grabbed the NuGet reference that applies Xunit analyzers. So these are all of the rules that I'll be seeing. So one of these is, for example, fact methods cannot have parameters. So what if I went ahead and tried to add one? So you can immediately see that I'm getting a code fix that says, oh hey, if you want to use a parameter, that should actually be an Xunit theory. So that can apply a code fix, so let's see. Oh, I think it's just prompting me too. So I could just convert that to a theory in order to get that to pass. So those code fixes and analyzers aren't provided by Microsoft, that was our tools that were then taken by the community and they ran with them and it's a very cool library to check out. Okay. Something else I love to call out during talks. Well, first I'll skip onto the resources so that you guys kind of have a launching point and then I'll talk about docs at the end because it's the last resource that I mentioned. So all of the tips and tricks for Visual Studio that I just showed you, you can, all the little code refactorings and everything I just went over, you can get a aka.ms slash vs 2017 guide. So that'll have much more documentation and actually write out all the keyboard shortcuts that I just used because I know that's hard to keep up sometimes when I'm just saying them out loud. You can go and grab the IntelliCode extension at aka.ms slash IntelliCode and if you are a NuGet package maintainer and you'd like to enable source link for the people consuming your package, you can go to github.com slash .net slash source link to find more information about how to hook up your source and how to publish your reference with what you need to enable source link. Throughout the demo I used live unit testing so that is an enterprise only feature. You can learn more about it at aka.ms slash live unit testing. So I know a lot of people really love to focus in only on the Visual Studio version 15.8 brand new features. So I went ahead and made like one page simple tutorial on all of the productivity 15.8 features. That's in my repository. It's on github slash kinderhaven slash productivity dash 15.8. So you can download that and check that out. It's a really simple, you just go straight through the file and enable all of the refactorings that I explain how to do in the comments on all of the methods. So the last thing I wanna call out and what I always like to kind of kind of a public service announcement is that our docs are open source and you can submit pull requests to them and they're wonderful to use. So I'll go ahead and go over there right now. So this is our Visual Studio 2017 C-Sharp Productivity Guide. Always you can change your theme from dark to light. Absolutely wonderful. I mean from light to dark and always leave it there. And I can hit this edit button and this will bring me right to where this document is hosted on github. So I think Myra Wenzel has a talk later during .NETConf. I think it's probably not tomorrow, but the next day. And I'm guessing she'll be talking all about our open source docs and how she maintains it. She does a ton of work on the .NET docs and it's wonderful to work with her. So you can easily navigate to where the doc is hosted on github and click this little edit button. And you can edit the doc right in your browser. You don't even need to actually clone the repository if it's a small change. And then you can propose the file change and make a PR request right in your browser. It's really easy to do, especially for docs. It's also kind of a good starter project. Anyway, so that was Visual Studio 2017 Productivity. Thanks so much for watching.