SOLID Presentation Slides

by Rasmus Kromann-Larsen October 27, 2009 21:20

A few weeks back I gave a talk in Odense .NET User Group (ONUG)  on “Practical SOLID in C#” about object-orientation and the SOLID principles.

Here is the slide deck for the presentation.

Download

Currently rated 3.8 by 4 people

  • Currently 3.75/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

kick it on DotNetKicks.com

Tags:

Why AAA style mocking is better than Record / Playback

by Rasmus Kromann-Larsen May 24, 2009 21:06

If you've followed me on twitter for more than a couple of days, you will most probably have heard my grumbling each time I run into issues using record / playback mocking - so I thought I'd write a short post on my experiences with both and why I think that I keep bumping into issues with record / playback.

Phases of a test

If you take a look at the normal flow of a test method without mocking, it will usually perform some kind of setup, then perform some action that invokes the code under test - and then at the end, make some assertions about the state of some component that you want verified. While some tests continue after this point, this is where you should stop if you're following the "one assert per test" rule - this is sort of the single responsibility principle for tests. This flow is also the inspiration for the AAA name - first you Arrange your test setup, then you Act upon the class under test - and then you Assert something about the state. Here's a simple example without mocking:

[Test]
public void CanRemoveCategories()
{
    // Arrange
    var collection = new CategoryCollection("test");

    // Act
    collection.RemoveCategory("test");

    // Assert
    Assert.That(collection.Count, Is.EqualTo(0));
}

This test is chronologically sound, it makes sense and it is easy to read - but then again, this is a state-based test, I said I was going to talk about behavioral tests - mock tests.

Phase confusion

Many people find that mocking is rather difficult to understand and that it often very hard to read and understand. Since our tests act as an API-description for our code - and since we want to be able to figure out how to fix our failed tests - readability is important. Now, let's look at one of my tests from a Record / Playback point of view. I'm using Rhino Mocks as my mocking framework in this test:

[Test]
public void ShouldIgnoreRespondentsThatDoesNotExistRecordPlayback()
{
    var guid = Guid.NewGuid();
    IEventRaiser executeRaiser;

    using(_mocks.Record())
    {
        Expect.Call(_view.Respondents).Return(new[] {guid.ToString()});
        Expect.Call(_repository.GetById(guid)).Return(null);

        _view.ExecuteOperation += null;
        executeRaiser = LastCall.IgnoreArguments()
            .Repeat.Any()
            .GetEventRaiser();

        Expect.Call(_view.OperationErrors = null)
            .IgnoreArguments()
            .Constraints(List.IsIn("Non-existant respondent: " + guid));
    }

    using(_mocks.Playback())
    {
        new BulkRespondentPresenter(_view, _repository);
        executeRaiser.Raise(null, EventArgs.Empty);
    }
}

Now, at a glance, can you tell me what this test is really doing? There's something with a view and a repository and we can probably deduce quite a bit from the test name. But it's rather hard to separate the different phases I talked about before Arrange, Act and Assert. Below, I've tried to annotate the test with the phases:

[Test]
 public void ShouldIgnoreRespondentsThatDoesNotExistRecordPlayback()
 {
     // Arrange
     var guid = Guid.NewGuid();
     // Part of Act
     IEventRaiser executeRaiser;

     using(_mocks.Record())
     {
         // Arrange (or Assert?)
         Expect.Call(_view.Respondents).Return(new[] {guid.ToString()});
         Expect.Call(_repository.GetById(guid)).Return(null);

         // Part of Act
         _view.ExecuteOperation += null;
         executeRaiser = LastCall.IgnoreArguments()
             .Repeat.Any()
             .GetEventRaiser();

         // Assert
         Expect.Call(_view.OperationErrors = null)
             .IgnoreArguments()
             .Constraints(List.IsIn("Non-existant respondent: " + guid));
     }

     using(_mocks.Playback())
     {
         // Arrange
         new BulkRespondentPresenter(_view, _repository);
         // Act
         executeRaiser.Raise(null, EventArgs.Empty);
     }
 }

No wonder it's hard to read and understand. The phases are mixed all over - and the Asserts are in the middle of the test - this is nothing like the natural flow of the previous test without mocking. I usually like to have the phases separated in my test with comments as well, but it's just not possible in this test. I wrote this test up rather quickly, so there might be a better way of doing it that I am missing - if there is, please yell at me :-)

Sorting out the confusion

AAA mocking, as the name suggests, is all about clearing out the confusion in that last test - it's about maintaining the original test flow. It just so happens also to have some other benefits, that I will get into later in the post. I've written the same test as above in an AAA style, this time with Moq, since I'm trying it out at the moment, but Rhino Mocks has similar syntax. Moq is pretty heavy on lambda expressions, but even if you haven't worked with those yet, I'm sure you will grasp the idea. If you want a general introduction to mocking with Moq, Justin Etheredge has a small series about it.

[Test]
public void ShouldIgnoreRespondentsThatDoesNotExist()
{
    // Arrange
    var guid = Guid.NewGuid();
    _viewMock.Setup(x => x.Respondents).Returns(new[] { guid.ToString() });
    _repositoryMock.Setup(x => x.GetById(guid)).Returns(() => null);

    // Act
    _viewMock.Raise(x => x.ExecuteOperation += null, EventArgs.Empty);

    // Assert
    _viewMock.VerifySet(x => x.OperationErrors =
        It.Is<IList<string>>(l => l.Contains("Non-existant respondent: "+guid)));
}

Those comments are actually in my original test as well - and in my test live template I generate all my tests with. If you compare this test to the one above, you will see that it has more or less the same components, but this time, they're arranged in a way that makes sense for the next reader of the test. The fact that the test is shorter is also slightly unfair, since my first test used an event raiser, which involves "many" lines of code. Also the separation of the phases allowed me to move the actual construction of the presenter our of the actual test and into shared setup code.

So what techniques did AAA mocking introduce to help alleviate the pains? First of all, the mocks no longer has states - that's what record and playback really refer to: A mock in record state will record calls made on it and then expect them to be called again during the playback state. Furthermore, it cleanly separates mock setup from mock expectations.

What is gained?

So what did we gain with AAA style mocking over the traditional record / playback style?

  • The main selling point for me is readability and test simplicity - it is much easier for me to explain mocking to someone else with AAA.
  • If you have done any fairly advanced record / playback mocking, you will find that when the mocks have states, it will often result in subtle test failures.
  • Clean separation of test phases.
  • Greatly improved ability to move shared code out of tests. Since you have the first part of your test handling setup, extending this part to start before the actual test (in a setup method) is no problem. With record / playback mocking, you will often run into state failures if you attempt it.

Currently rated 5.0 by 4 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

kick it on DotNetKicks.com

Tags:

Development | Testing

Be Mindful Of Your Dependencies

by Rasmus Kromann-Larsen May 11, 2009 20:35

Dependencies are everywhere in your code, you cannot avoid them, without dependencies, your software would make no sense, it is the interaction and collaboration between the software entities that create the program. Now this statement doesn't mean that we should not worry about our dependencies - we just can't remove them completely. But as with almost any other aspect of good software development, we should be mindful of our dependencies.

Coupling

When a software entity depends on another, they are said to be coupled. Coupling ranges in degrees from totally decoupled over loosely coupled to tightly coupled. The tighter two software entities are coupled, the bigger risk that when one changes, the other will be forced to change as well. Why is this important? Because coupling is transitive (if A depends on B and B depends on C, A indirectly depends on C) and we would like to be able to change our program in the future. If you have a program where all components depend on each other and the coupling is high, a small change will often ripple through the system - either a) forcing you to change a bigger part of the system (potentially creating more ripples) or b) breaking the system in unexpected places. If not treated properly, these ripples can cause developers to loose confidence in their changes (what will I break this time?) and slow development down - maybe even to a halt.

Cohesion

Cohesion describes how related the responsibilities within a component are, how focused it is. This relates to the functionality within the component - a static utility class will often have rather low cohesion. But it also relates to the level of abstraction used within the component - again, a class that does both very high level operations and very low level operations will often have very low cohesion. Code with low cohesion will often be harder to understand, since it doing many different things. It will often be easier to reuse a component with high cohesion, since it will be more focused on doing a single task.

Managing Dependencies

So how do we manage dependencies? As mentioned, we can't get rid of them - but we can choose to decouple our software components from each other - and we can work to increase the cohesion of our components. Looking into the Gang of Four book, some basic advice is available:

  • Program to an interface, not an implementation.
  • Favor composition over inheritance.

Interfaces

Decoupling often involves programming to an interface instead of an implementation. Interfaces can help us break our dependency chains - looking at the example from before: If A depends on B and B depends on C - we can break the dependency chain by making an interface IB of B. Now A depends on IB instead. Interfaces, when used properly, can be seen as concepts and are thus more "stable" than an actual implementation. It is a contract that describes a set of properties for some object to fulfill. If you were to build a tall tower, would you prefer to have the core of the tower made of stable building blocks or instable ones?

Having an interface also allows us to tweak other things, such as the granularity of access - the size of the surface on which A is dependant. If we reduce the size of the interface and thus the dependency, A's usage of B will be easier to control - and new concrete classes based on IB will probably be easier to implement and have higher cohesion too.

Composition

Another factor that can help us reduce coupling is to favor composition over inheritance. I like the analogy from the Gang of Four book where they talk about inheritance as white-box reuse, while composition is black-box reuse. What this means is that a sub-class will often be tightly coupled to the internals of the parent. In languages like C# and Java, single inheritance limits your options even further, once you start inheriting - and languages with multiple inheritance often suffer from other problems.

Composition on the other hand, is all about creating small units of focused behavior and then "weaving" this behavior into the desired functionality. With composition, different components are free to vary independent of each other - whereas this might cause combinatorial explosions in inheritance trees.

This is not to say that inheritance is not useful, but it is often overused - composition is often a little harder to grasp at first (I know it took me a while), but it is a really powerful technique.

Conclusion

In this post I have discussed some of the basics about managing dependencies. It is on a reasonably low level, but will be the basis for some of my next posts on design principles and design patterns - since many of them build upon exactly this.

Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

kick it on DotNetKicks.com

Tags:

Design

Code Quality and Software Entropy

by Rasmus Kromann-Larsen March 31, 2009 22:05

complexityCode is an odd thing, it can be beautiful, ugly, horrible, elegant, it can smell - some people even compare code to poetry. If you are a developer, you will know that there are an almost infinite number of ways that you can write a piece of code with the same functionality. The way chosen will affect the different qualities that the code - and thus the program as a whole - will exhibit. These qualities are things like performance, testability, robustness, security, scalability etc.

However, when developers talk about code quality (at least when I do) the main focus is often maintainability and flexibility. From my point of view, any software project is always decaying, especially if you have multiple people working on it, hacks are made, designs are twisted into fulfilling new responsibilities that their original creator didn't foresee or intend. Even with a clean design and a focus on maintaining high quality, the amount of code is almost always increasing with new functionality, as is the programs complexity. This is sometimes known as software entropy - chaos. If this entropy is ignored over longer periods of time, the technical debt incurred will keep increasing until the interest is so high that the project will grind to a halt - creating new features takes a long time and introduces many new and interesting bugs.

Maintainability is important on most projects, it often depends on the complexity of the program and the expected lifetime - so if you are doing prototypes or mock-ups, focusing on maintainability may not be beneficial, although in my experience, when management sees a really cool prototype, they often feel like building a project on top of it. Most software projects will have a rather long lifetime, often with multiple versions and a need to maintain the project even after it has shipped.

Obtaining high code quality is a craft, it requires discipline and continuous refactoring and improvement. This will be the main topic of my blog for a while, save the random posts about ReSharper or other intriguing things that may come up. Topics within this field off the top of my head: Unit testing, design principles (SOLID and others), design patterns, understanding and taming dependencies, inversion of control containers, simplicity and many more - ideas are welcome.

Currently rated 3.3 by 4 people

  • Currently 3.25/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

kick it on DotNetKicks.com

Tags:

Craftsmanship | Development

ReSharper Series - Part 6: Find Usages

by Rasmus Kromann-Larsen March 09, 2009 21:54

This is the 6th post in my ReSharper Series - this time we are going to look at how to find usages of particular code members in your code. While plain old text search can be useful sometimes, a structured search is really awesome for getting a good overview. In addition, the standard ReSharper setup on this feature is rather bad compared to what is possible, so a bit of UI tweaking (very simple) is also available.

Find Usages

Find usages works on almost all code elements, be it classes, methods or variables, invoking it by pressing Shift+F12 [IntelliJ: Alt+F7] will open a result window, which show the places in your project / solution where the element is used. Using the ASP.NET MVC source, in the Controller class, invoking Find Usages on the ModelState property:

image

This gives us the following results window:

image

Usages are presented on a namespace level, showing the line of code that includes the given element. Double-clicking or hitting Enter on a line jumps to the file.

Pimp My Search Results

While this results window is useful, you would often like slightly more information. In the options row of the Find Usages window, there is a group by drop down, which is set to Namespace as default - and most people I have seen using ReSharper never change this.

image

There are a lot of grouping options available, as shown above - I usually prefer the Namespace and Type option, giving me the same Namespace overview that I had before, but allowing me to see the names of the actual classes that use the element.

Another useful option is the Show Preview option, also found on the options row of the Find Usages window. This is disabled by default, but enabling it will show a preview of the code surrounding the selected line in the search results.

image

Since I usually have my Find Usages window docked in the bottom (auto-hiding though) of my screen, I prefer setting the Show Preview to Right.

With these small tweaks, the Find Usages window now look like this:

image 

Go To Usage

Sometimes you are not interested in looking at the results of your search in the Find Usages window - you have your cursor at some code element and you want to navigate directly to a usage. Hitting Alt+Shift+F12 [IntelliJ: Ctrl+Alt+F7] will bring up a code-completion-like-menu to quickly jump to a usage. Invoking this on the ModelState gives us the following result:

image

Selecting an item from the list jumps directly to usage. In a later post, we will explore more of these quick-navigation options from directly within the code editor.

Currently rated 4.0 by 2 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

kick it on DotNetKicks.com

Tags:

ReSharper

Craftsmanship In The Wild

by Rasmus Kromann-Larsen March 07, 2009 22:38

imageI was out dining today and had an experience I simply had to share.  It was a moderately expensive restaurant and they had cocktails as part of their menu.

As my after dinner cocktail, I chose a Mojito, which is actually a fairly difficult cocktail to make properly - at least if you want it to be as strong as it ought to be, while still masking the taste with the proper levels of sugar and mint.

I watched as the bartender mixed the drink - he didn't measure, but he was focused on the task at hand - he even tasted the drink elegantly with a straw to check its quality. The Mojito was extraordinary - perfect - it was so good that I felt like I really needed to order another one. However, this time, a girl, clearly an apprentice bartender wanted to make my next drink. She used the same ingredients but her focus was all around, she didn't sample the drink, just mixed everything approximately as she had been told. Watching the process, I wasn't surprised when the drink was a disappointment - it was too sweet and kind of watery.

As I asked for the bill, at the first bartender, I complimented his craftsmanship and mentioned that the second Mojito had not quite been what his had been - he immediately cut the cost of the second drink in half. He didn't even blink.

What kind of bartender do you want to be?

Currently rated 4.7 by 6 people

  • Currently 4.666667/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

kick it on DotNetKicks.com

Tags: , , ,

Development | Craftsmanship

ReSharper Series - Part 5: Generating Code

by Rasmus Kromann-Larsen March 04, 2009 21:55

Welcome to the 5th part of my ReSharper Series - in this post we are going to take a look at how you can easily generate a lot of the fluff code that surrounds your real functionality.

While C# is a great language, there is a quite of bit of the code that you write every day that feels somewhat crufty. It is these standard things that we do a thousand times, like writing constructors, properties, backing fields to said properties (better with automatic properties - but you still often need a backing field). Luckily, ReSharper can help ease your pain - or at least let you focus on writing that core functionality - and not worry about the cost of adding another class (in terms of typing).

Generating Class Members

We have already the power of Alt+Enter in one of the earlier posts - and this a tool that most people I have seen use for creating new code.  It can do stuff like implementing missing methods and assigning creating backing fields for you from constructor arguments. If we use it on our balance argument that is unused (gray), ReSharper offers the following options:

image

However, we might want more - we had to write the constructor ourselves - and we have to create the property afterwards. Let's introduce another shortcut - Alt+Ins. While Alt+Enter is a general purpose tool, Alt+Ins is focused on generating code. Use it anywhere in a class and you will be presented with the following options:

image

Generating a constructor will bring up a dialog allowing you to select which members / properties you want to initialize from the constructor. Read-only properties / Properties will give quick options to create read-only properties from whatever backing fields you already have in your class. Implementing missing members will create any members not yet implemented from interfaces or abstract base classes. Equality members will implement Equals and the equality operators - GetHashCode included, based on the properties / fields you choose. Formatting members will introduce a ToString method that contains the values of whatever properties / fields you want.

The last one I didn't mention is the one I think is mostly underused - it is the Delegating members option. It is often useful in object oriented design to encapsulate another class and provide delegated methods for a number of the contained type's methods. The perfect example is when implementing the decorator pattern - this pattern, by design, requires you to delegate all the methods the contained type. This is a pain to do by hand. However, let's try using the delegating members option in my Account class, after adding a List<int> - like so:

image

This brings up the following dialog:

image

So basically, ReSharper lets me pick and choose any or all methods / properties that I want to directly delegate. For this class, maybe I need the Add and indexer methods, so I check them off and hit finish:

image

The code for delegating members is silly simple - and this is EXACTLY why we want to generate it in the first place. Generating delegating members let me focus on my intent of which options I want to expose from my class instead of the laborious task of typing out the code.

Generating Files

As a final note in this post, I would like to introduce another usage of Alt+Ins which I have grown quite fond of - in the solution explorer, pressing the shortcut will allow you to add new files in a more lightweight way than the usual add file dialog:

image

Later, when we look at live templates, we will also see how to add your own file templates to this menu.

Currently rated 3.0 by 1 people

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

kick it on DotNetKicks.com

Tags: ,

ReSharper

Code Coverage – What You Need To Know

by Rasmus Kromann-Larsen February 23, 2009 00:34

People often talk about the percentage of code coverage they have from unit tests, whether it be actual coverage or the goal they or their project have set. Having a high coverage percentage is often seen as a quality, but code coverage is not really a metric that gives much value in itself. In this post I want to investigate the different types of code coverage that exists and address some of the problems with code coverage.

Types of Code Coverage

There are various forms of code coverage, not just the one we seem to always talk about. A short introduction to some of the existing coverage types:

Statement coverage – How many percent of statements / lines have been covered?

Branch coverage – How many percent of branches (control structures) have been covered? In the case of an if statement, has the expression evaluated to both true and false. There are variations of branch coverage that talk about more detailed decision coverage, like covering all permutations of true and false in an expression that contain stuff like AND and OR.

Path coverage – How many percent of all possible paths have been covered? This may not sound too different from the two above, but it is actually much more complicated. An example could be a function with two simple if statements (A and B) after each other. To obtain full path coverage, you would have to get all four permutations of true and false in the two if statements (A B - !A B - A !B - !A !B) whereas in statement coverage you would only have to exercise the if statements in isolation. Mind you that this is the simple case – if statements with multiple sub expressions, nested ifs and loops are much worse.

The coverage type we usually talk about is actually statement coverage – but as you can see from just looking at branch and path coverage, much is left to be desired. Coverage types like path coverage are also hard to measure, as many loops will have a near-infinite number of paths.

Another thing that is very hard to measure with code coverage is multi-threaded behavior. It is definitely not caught in our statement coverage and if getting full path coverage is hard, consider getting full path coverage with multiple threads.

One Problem – Test Quality

The problem with using code coverage on its own is that code coverage tells you nothing about the quality of the tests that cover the code. Code coverage tells you how much of your code has actually been executed, but it tells you nothing about the asserts that were made in the tests – that is, it says nothing about the correctness of the code.

The perfect example of this is writing a test with zero asserts (state or interaction). This test will produce a certain percentage of coverage, while ensuring nothing except that the code can successfully execute. While such sanity tests can be useful in some tricky cases with exceptions, this is often a worthless test – it has no quality whatsoever, it doesn’t verify any intent of the programmer who wrote the code it is testing.

The thing that is easy to sell about code coverage is that is is reasonably easy to measure. It is easy to set a percentage, a goal and then try to obtain this goal. 100% code coverage is a great goal – it might be unrealistic in most situations, but it is a good thing to strive towards. But if the tests suck or the programmers who write the tests become lazy the code coverage will be nothing but misleading.

The problem with test quality is that measuring it is really really hard – at least programmatically. How can you even begin to measure how much this code matches the intent of the programmer. Usually the number of asserts that make sense for a given test match only a very low number of the values in the system. And even if we could measure test quality using a program, we might as well do away with the tests and just measure programmer intent versus the real program.

The solution, to me, is discipline and good engineering principles. Code coverage can be really valuable to a team that treat their test code like production code, sharing ownership of the code and doing regular inspections / code reviews to ensure that the test quality is high.

The Inverse Property

One of the things I like best about code coverage is it’s quality as an inverse property – that is, a tool that can specifically tell me which parts of my code that I have not tested. This is a clear signal that you need to be more careful when touching this code.

This is also one of the reasons that I actually like to remove tests that either are very low quality or haven’t kept up to date with the intent of the code they are testing. The ideal solution is to rewrite the tests to match the intent of the code / desired quality, but this is not always realistic. To me, such tests are more harmful than no tests at all – they give a false sense of security and will only confuse if anyone look at them. At least if there is no tests my coverage tool can tell me there is a problem in this part of the system.

And while we are at it, it is actually amusing that some people treat test code like it is nowhere near production code and then the same people seem to think that it is blasphemy to delete even a single test. Treat your test code like your normal code, delete / rewrite it if it is obsolete or doesn’t make sense. Maintaining code that doesn’t add value to the system makes no sense.

Conclusion

Code coverage is a useful metric, but often not in isolation. If you use it then be aware of the implications of the way you’re using it, increasing test quality is much more valuable to me than reaching a specific coverage percentage, although it is good to have some sort of goal. Write tests to verify intent, not to increase the coverage percent – use coverage to find the intents not covered.

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

kick it on DotNetKicks.com

Tags:

Development | Testing

ReSharper Series - Retrospective?

by Rasmus Kromann-Larsen February 10, 2009 22:44

Now, I've written the first 4 (7 really) parts of my ReSharper Series - I was a bit curious if anyone is actually reading it - and if anyone is getting value from it? Personally I am learning quite a bit more than I already knew about ReSharper. So a few questions:

  • So, are the topics too basic? Too advanced? Too long posts?
  • Would it be better with screencasts? I feel it can be kind of hard to show the speed that you can obtain with ReSharper using simple screen shots.
  • Are there anything in particular you would like to hear about? Hear more about something that has already been mentioned?
  • Other suggestions?

I am going away on ski vacation next week and then to Copenhagen for a few days after that (for the MDIP meeting), so there's probably not going to be any more posts until I get back in about 2 weeks.

Hope to get a few useful comments (or mails) on this post.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

kick it on DotNetKicks.com

Tags:

ReSharper

ReSharper Series - Part 4: Moving Code

by Rasmus Kromann-Larsen February 10, 2009 22:33

Welcome to the 4th part of my ReSharper Series. Today we are going to look at one of my new favorite ways to use ReSharper - to move code around. We haven't dipped into refactoring really yet, and today isn't really going to be that much about it - this is moving code on a lower syntactic level - shortcuts to save that copy / paste. In addition, we are going to have a little bit of code navigation that plays well with this feature.

Furthermore, since many people use the VS binding mode in ReSharper, I am going to try and supply both binding sets in the future. I might even go back and change the previous posts at some point - today all the bindings I will show work for both binding modes though.

Navigating Methods

The first small feature is navigation between members. Basically what it gives you is a way to quickly navigate between methods in your class. If you are in a method like so:

image

Pressing Alt+Arrow Down will navigate to the next method, while using Alt+Arrow Up will send you to the method signature, like so:

image

When at a method signature already, you can jump up and down between method signatures in the same way.

image

This comes in handy when moving methods, since you need to be at the method signature to do so.

Moving Code

The shortcuts for moving code involve a lot of keys, but they are pretty easy to remember. You can move code over 2 axis, up/down and left/right. This is controlled using the arrow keys. To enable the move functionality, you need to hold down Alt, Ctrl and Shift.

Moving Methods

Let us look at the first example. With our cursor placed on the method signature of the Withdraw method, we hold down Alt, Ctrl and Shift to enable movement. This will make the block of code we are moving turn a light cyan (with my color scheme at least):

image

Hitting the move up shortcut (Alt+Ctrl+Shift+Arrow Up) sends our method above the Deposit method like so:

image

We can also move methods down using Alt+Ctrl+Shift+Arrow Down. Quite a bit easier than copy pasting it - and useful for reordering methods quickly if combined with the method navigation above.

Moving Arguments

Now we can move quite a bit more than methods. Say we have a method call where we wanted to move the arguments. We can do so using Alt+Ctrl+Shift+Arrow Left and Alt+Ctrl+Shift+Arrow Right. Again, as we hold down Alt, Ctrl and Shift, the block we are about to move is highlighted:

image

And sending it left is easy:

image

This also works for actual method signatures, just be aware that this doesn't actually refactor your method and change all the call sites for the method (although ReSharper can do this in it's refactor menu - look for the Change Signature refactoring).

Moving Statements

When we are dealing with statements inside a method, it can some times be useful to reorder lines of code or move code in and out of control structures, so when we hold down Ctrl, Alt and Shift here it actually suggests that we can use all 4 directions.

image

Moving up and down lets us maintain our level of scope, in this case, pressing Alt+Ctrl+Shift+Arrow Down, we would send the method call into the else branch:

image

Repeating this would send it below the negativeText call. When we move left and right, we move in and out of scopes, thus if we press Alt+Ctrl+Shift+Arrow Left, we yank the statement all the way out of the entire if statement:

image

Again, if we move up and down here, we maintain our level of scope and thus do not re-enter the if statement unless we move the statement right.

image

Reordering Expressions

The last short example is reordering expressions, this makes it easy to reorder expressions and move parts of them around. Like here:

image

Moving Balance right would actually swap the two values.

image

Summary

What I have shown is some of the possibilities for moving code, but as always, play around with it - you can move quite a bit more - like fields and properties in your classes - possibly a lot more.

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

kick it on DotNetKicks.com

Tags:

ReSharper

Powered by BlogEngine.NET 1.4.5.0
Theme by Mads Kristensen | Modified by Mooglegiant | Adjusted by Rasmus Kromann-Larsen

About Me

I am a danish .NET developer blogging about the technical side of my life, mostly .NET stuff, but also fundamental topics like design patterns, principles and productivity boosters.

In addition, I am a core group member of Aarhus .NET User Group.