Unable To Step Into .NET Source

I began getting a problem a while ago that I was unable to step into the .NET source in Visual Studio 2008.  It happened suddenly, and I noticed it shortly after installing SP1.  Given my observation it appears to be due to upgrading the SP1; but I couldn’t find anyone else not having the same problem.  I had another computer where it worked, so I basically put it aside.

Today I had a chance to have a closer look.  I had configured 2008 (RTM, not SP1) to get the .NET source based on Shawn Burke’s blog and had not encountered any problems.  Once I upgraded to SP1 and checked “enabled .Net source stepping”, I all I ever got when trying to step through source is a dialog asking me for the location of the CS file.

What I had configured was to place the debug symbols into a folder in the Visual Studio 2008 user directory (c:\Documents and Settings\PRitchie\My Documents\Visual Studio 2008\Symbols, for example).

Despite creating a new subdirectory for SP1, I still could not step through the source.

It wasn’t until I moved the directory down the hierarchy that I finally got some joy.  I first tried it on the root and it worked fine.  I then tried it as a sub directory within my documents and it worked fine.  I imagine that the path was longer that 260 and rather than present the user with an error with that detail it assumed it couldn’t find the file it was looking for and asked the user for the location of it.  But, I’m guessing.

Hope this helps someone else.

DotNetKicks Image

Pass-through Constructors

Pass-through constructors is a term I use to describe parameterized constructors that have none of their own logic and simply pass parameters to the base class.  For example:

    public class BaseClass

    {

        private String text;

        public BaseClass(String text)

        {

            this.text = text;

        }

    }

 

    public class DerivedClass : BaseClass

    {

        public DerivedClass(String text)

            : base(text)

        {

        }

    }

DotNetKicks Image

Pontificating Virtual Parameterized Constructors in C#

Tom Hollander recently posted about a change he required to the Enterprise Library for date/time validation.  He had to create a new class (rather than modify the Enterprise Library) that derived from another, defective class.  One of his complaints was that in order to effectively implement the base class he had to also write matching constructors that simply called the base class.  His suggestion was effectively to add the concept of virtual parameterized constructors to C#.  I detail “parameterized constructors” because C# already effectively has virtual default constructors.  In the following example the base constructor (Form()) is automatically called by the derivative:

    public class MyForm : Form

    {

        public MyForm()

        {

        }

    }

Virtual parameterized constructors are not new, and from a mere language standpoint this seems reasonable.  Pragmatically though, I believe, this is another story.  It seems logical to be able to simply inherit the parameterized constructors of the base class; but, there are so many times that this isn't the case or some generally accepted principles that would be contravened by a language addition like this.

Let's first look at the open/closed principle (OCP).  The OCP suggests classes should be open for extension but closed for modification.  Robert Martin suggests [1] properly designed class hierarchies that obey OCP implement an abstraction; i.e. derive from an abstract class or implement an interface.  For example:

public interface IShape

{

    void Draw(Graphics graphics);

}

 

public class Rectangle : IShape

{

    //...

    public void Draw(Graphics graphics)

    {

        ///...

    }

}

 

Second, let's look at the "prefer composition over inheritance" principle.  The effect of a language change like this on a design that prefers composition should be fairly obvious.  Here's an example of this principle:

public interface IPolygon {

    void Draw(Graphics graphics);

}

public sealed class Polygon {

    private readonly Point[] points;

    public Polygon(Point[] points) {

        this.points = points;

    }

    public void Draw(Graphics graphics) {

        for(int i = 1; i < points.Length; i++) {

            graphics.DrawLine(Pens.Black, points[i-1], points);

        }

    }

}

 

public class Rectangle : IPolygon {

    private readonly Polygon polygon;

    public Rectangle(Point location, Size size) {

        Point[] points = new Point[5];

        points[4] = points[0] = location;

        points[1] = new Point(location.X + size.Width, location.Y);

        points[2] = new Point(location.X + size.Width, location.Y + size.Height);

        points[3] = new Point(location.X, location.Y + size.Height);

        polygon = new Polygon(points);

    }

    public void Draw(Graphics graphics) {

        polygon.Draw(graphics);

    }

}

 

Obviously there is no way to use virtual parameterized constructors here.

Clearly, designs that take into account OCP and prefer-composition-over-inheritance would not benefit from a "virtual parameterized constructor" language addition.

Finally, let's look at why a class might have many constructors causing such friction for derivatives.  There's many reasons why a class might have many constructors.  I believe all are indications of a poorly designed class.  My first thought would be that many constructors is a result of a large class and that the large-class-code-smell should be an indication for redesign.  A large class could be in an indication of a motherclass; but in either case this is likely a single responsibility principle (SRP) violation and the class is doing much more than it should and be redesigned.  If the class isn't large but has many constructors, this was likely done not in response to how the class should/would be used but to cover every possible way of constructing the type.  This would then be a YAGNI violation and the number of constructors should simply be pared down.

But, what about when you have to deal with poorly design hierarchies and don't have the ability to modify them?  A valid point; but, simply for the lack of friction of writing pass-through constructors I don't think adding to the language to support poorly designed classes is a good for the language or its developers.

While an addition like virtual parameterized constructors seems benign, its limited actual usefulness makes the effort not worth the reward.  Plus, it introduces greater abilities to create poorly designed types.

[1] http://www.objectmentor.com/resources/articles/ocp.pdf

DotNetKicks Image

DevTeach 2008 Includes over $1,000 In Free Software.

Announced recently, registering for and attending DevTeach Montreal 2008 will land you with $1,000 of free software.  Including:

  • Visual Studio 2008 Pro
  • Expression Web 2
  • TechEd Conference DVD set

The sessions have shaped up to be some of the best training money can buy, now you get a bunch of free software to boot.

For more details on the free software see: http://www.devteach.com/News.aspx

For a look at the sessions see: http://www.devteach.com/Schedule.aspx

To register go to: http://www.devteach.com/Register.aspx

.NET 4.0, Evolving .NET Development

.NET 4.0 is the first release of .NET since 2.0 that evolves .NET for every programmer.  .NET 3.0 was largely LINQ and .NET 3.5 was largely new namespaces (like WCF, WWF, etc.)

.NET 4.0 evolves the programming and design for any programmer.  It offers framework support for parallel processing (PFX will be released), Code Contracts (now DbC is a reality at the framework level, and opens the possibility of it being a reality at the language level post 2010), variance changes (co- and contra-variance on generics interfaces and delegates is now a reality).

Parallel Processing
Moore's law has changed from single processors doubling in speed every 18 months to doubling in processing power through increased core count every 18 months.  This means for applications to make use of processing power increases they must increasingly make use of parallel processing and multi-threading.  The PFX makes this more a reality by providing a framework by which application designers can more easily write code to support multi-core processors and multi-processor computers.

With PFX writing a loop to make use of multiple processors (while still supporting single processors) will be as easy as:

    uint[] numbers = new uint[] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
    Parallel.ForEach(numbers, delegate(uint number) { Trace.WriteLine(CalculateFibonacci(number)); });

Code Contracts
Design by contract is a form of writing software with verifiable interface specifications.  These specifications can be used at compile time to find code that breaks the contract and not require checking of the contract at run-time.  For example:

    [ContractInvariantMethod]
    public int Calculate()
    {
        int result = 0;
        foreach (int value in values)
        {
            this.operation(ref result, value);
        }
        return result;
    }

If anything modifies the current class within the Calculate method, an exception will be thrown at run-time.  Compilers will eventually be able to perform rudimentary checks at compile-time to ensure these contracts are abided by.  For example:

    [ContractInvariantMethod]
    public int Calculate()
    {
        int result = 0;
        foreach (int value in values)
        {
            this.operation(ref result, value);
        }
        this.date = DateTime.Now;
        return result;
    }

...may eventually cause a compile error on the assignment to this.date.  The person designing this type intended this method to be invariant, meaning it doesn't change the state of the object to which it belongs.  This design attribute can now be guaranteed.

Being able to include more design aspects in code and code definitions is a great step forward in not only writing intention-revealing code but in the ability to write more reliable code.

Variance changes

C# has always had intuitive variance when it came to arrays.  For example, the following is valid code:

    Shape[] shapes = new Triangle[10];

Given:

    class Shape {
        //...
    }
    class Triangle : Shape {
        //...
    }
 
Generics variance was a different storey.  Prior to Visual C# 2010, this following is a compile error:
    Func<Triangle> triangle = () => new Triangle();
    Func<Shape> shape = triangle;
 
...despite Triangle being a type of shape (or otherwise known as "bigger" than Shape).  This is known as invariant. In Visual C# 2010 you can now create delegates (as well as types and methods) that are no longer invariant.  For example, a Func delegate could be created that is covariant:
        delegate T Func<out T>();
(not the new use of the out keword) ...which could make our previous code:
    Func<Triangle> triangle = () => new Triangle();
    Func<Shape> shape = triangle;
...compiler without error.
 
The same can be done for contravariance with the the new use of the in keyword:
        delegate T Action<in T>(T value);
 
For more details on generics variance, please see Eric Lippert's series on generics variance: http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx

Other
Another notable improvement is side-by-side (SxS) support for multiple versions of .NET.  This allows hosting of more than one version of the CLR within a single process.  This makes writing shell extensions, for example, in C# a reality in .NET 4.0.  You shouldn't need to target .NET 4.0, but as long as .NET 4.0 is installed you should be able to write shell extensions in a current version of .NET (like .NET 2.0) and it will be supported.  Prior to .NET 4.0, a process could only have one version of the CLR loaded into a process, making extending 3rd party native applications (like the Windows shell) very problematic because what version of the CLR that was loaded into a process would depend on the first extension loaded.  If the first extension loaded was a .NET 1.1 assembly then any other extensions loaded requiring .NET 2.0 would subsequently fail.

DotNetKicks Image

Microsoft Techdays 2008

I've been lax on posting about my involvement in Microsoft Techdays 2008.  I'll be doing two sessions in Ottawa.  One is titled "Internet Explorer 8 for Developers - What you need to know".  The other is "Blackbelt Databinding in WPF".

The description of Internet Explorer 8 for Developers - What you need to know:

Internet Explorer 8 has plenty of exciting new features for developers, from Web Slices and Activities, to new support for HTML5, CSS2.1, and CSS3. In this session, you'll learn how to utilize these features in your latest and greatest Web applications. You'll also learn how features like Compatibility Mode can help preserve the user experience during development.

The description of Blackbelt Databinding in WPF:

Most rich applications present data, often lots of it. To avoid writing lots of code to support the presentation of that data, you should take full advantage of the data binding capabilities of your presentation platform. In this session we discuss and demonstrates the data binding capabilities of WPF. You will find out what data contexts are and how they work with the element hierarchy. We will show you what Bindings are, how to declare them, and what optional capabilities they support. We will demonstrate binding to data sets as well as custom objects and collections, and discuss considerations for implementing those types. In this session we show you how to use data templates to define reusable chunks of UI that can be rendered automatically for each item in a data collection. We also discuss the way you can interact with your bound data programmatically to control the presentation of that data and to make changes to it in code.

For more information on Techdays in general, see http://www.microsoft.com/canada/techdays/default.aspx.  For more information on the sessions in Ottawa, it's location, etc., see http://www.microsoft.com/canada/techdays/sessions.aspx?city=Ottawa.

If you're coming to any of the Ottawa sessions, track me down and say HI.

 

Posted by PeterRitchie | with no comments
Filed under:

Closure Tip

In C# 2 and greater you have the ability to write closures.  A closure is a function that is evaluated in an environment containing one ore more bound variables[1].  In C# 2 this is done by creating an anonymous method that accesses a variable declared outside the body of the anonymous method.  Writing closures (which can evolve from an anonymous method that is not a closure) must be very deliberate and must be given great attention.  Closures offer a very specific way of essentially creating code at runtime based on runtime values.  But, with closures, they can be bound to a mutable variable.  When you bind to a mutable variable you get the value of the variable when the closure is run, not when the closure was created.  You intuitively expect to get the value when the closure was created, not when it was executed.  For example

            String[] numbers = new[] {"one", "two", "three"};
            List<MethodInvoker> delegates = new List<MethodInvoker>();
            foreach(String number in numbers)
            {
                delegates.Add(delegate() { Trace.WriteLine(number); });
            }
            //...
            foreach(MethodInvoker method in delegates)
            {
                method();
            }

With this code, you would expect the following trace:

one
two
three

But, you get this:

three
three
three

This is because the anonymous method is bound to the variable number which was “three” when the anonymous method was executed.

But, what can you do to create an anonymous method at runtime that will output the value of a specific value in a collection?  Well, the answer is very simple, bind to a variable that doesn’t change.  For example:

            foreach (String number in numbers)
            {
                String text = number;
                delegates.Add(delegate() { Trace.WriteLine(text); });
            }
            foreach (MethodInvoker method in delegates)
            {
                method();
            }

The addition of the text variable that is simply initialized with the value of number means the closure isn’t bound to a mutating variable and end up getting results that are more intuitive:

one
two
three

In C# 3 you also have the ability to write closures in the form of lambdas.  You could do the same as the above with lambdas as follows:

            foreach (String number in numbers)
            {
                String text = number;
                delegates.Add(() => Trace.WriteLine(text));
            }
            foreach (MethodInvoker method in delegates)
            {
                method();
            }

Related advice may be found in Item 33 of Bill Wagner’s More Effective C#.

With Resharper you get an added warning that warns you that you’re accessing a modified closure.  So, in the first example, the IDE would show number as the WriteLine parameter as a warning.

[1] http://en.wikipedia.org/wiki/Lexical_closure

DotNetKicks Image

Developing with Source Code Control Best Practices Part 1

This post will detail some first principles about source code control (SCC) and provide what I consider the most basic of practices that every dev should follow.

What is SCC?
SCC provides developers the ability to keep a history of their changes.  SCC allows developers the ability to group file changes together with an annotation. SCC allows developers the ability to get back to the state the project was in at any given point in time, arbitrary or specific (Beta 1, RTM, etc.).  SCC provides development teams the ability to more easily work on the same files at the same time.  SCC allows developers to see who did what, when, and usually why.  SCC allows development on more than one branch of the code at a time.  Depending on the SCC, SCC allows developers to link changes to tasks, work items, etc.

Basic practices
Never check in changes that cannot be built.
This is pretty self-explanatory.  Referring back to what is SCC: "SCC allows developers the ability to get back to the state the project was in at any given point in time".  This means anyone can get back to a state where the project won't build if you check in changes that cannot be built.  This causes undue friction at points temporally distant from the changes--which means there lots of work (time) involved to find and implement a solution (e.g. is the state 5 seconds before better, is the state 5 seconds after better, etc?  All things that need to be researched and tested before continuing--wasting time and resources).

Check in related changes atomically.
This builds on the first practice, if all related changes are checked in as a unit the likelihood of that check-in breaking the build is highly improbable.  Atomically means all related changes are checked in at the same time.  With most SCC systems this is extremely simple, and usually means selecting all the files you have edited (or all the subfolders you have modified folders in--or the one subfolder if you have unrelated changes, see part 2).  This might mean avoiding SCC IDE integration if your changes span several solutions. If you can't check in changes atomically (really question this if you think you can't.  If you honestly can't, I'd suggest changing SCC systems) order the check ins to avoid build problems.  For example, if you added an enum to somefile.cs, then used that new enum in someotherfile.cs, check-in somefile.cs before checking-in someotherfile.cs.  Checking in somefile.cs first will not put the source code in a state where it cannot be compiled.  You're working on a team, anyone on the team can get the state of the project at any time, like between non-atomic file check ins.  This means they get code that doesn't compile and they won't know why or how to fix it--blocking them from doing their work and wasting time and impacting the project schedule.

Make use of shelving.
If what you've coded needs to be given to someone else to get the source code to build properly, don't check it in in order to give it to that other person.  On cases like this, if your SCC has shelving or shelvsets, shelve the changes and inform the other person of the shelvset instead of checking in.  Let them check in the working changes as an atomic unit.  If shelving isn’t an option (consider or petition for an SCC system that does, then), send them the files for them to check in after modifications.  See next practice.

Get all current code and build before checking in.
Someone may have made changes between when you got the code you working on and when you want to check in.  If you don't get the latest code (and potentially merge it with yours), what you check-in may leave the controlled code in a state where it cannot be built.  Get all the current code to make sure you have what will be the state of the code when you check in and that it builds first.  If your build process is long, this may require several tries.  You should address build times if this is a common problem.  Communicate to the rest of the team that you need to check in changes and that they hold off on checking in related components if necessary.

kick it on DotNetKicks.com

Software Process and Reduction of Quality

Ken Schwaber had a conversation with Scott Hanselman about the concept of "done".  He said that software developers have a habit of culling down all the generally accepted practices of software development except the writing of code.  He says that, when pushed, software developers reduce quality in an effort to produce a software product by a certain time.  This leads to a huge debt that must eventually be paid. 

These generally accepted practices include things like unit testing, refactoring, design, documentation, etc.  In the case of producing an API or and SDK, I believe these practices includes community involvement.  When a team developing an SDK, API, or IDE "goes dark", they're not doing their job properly--they're ignoring the fundamental reason for their work: the customer.  This is a huge problem in our industry because software developers are effectively trained that schedules only include writing code and meetings.

I agree with Ken and would say that part of an Agile process includes a significant amount of time to communicate with customers need be scheduled.

Even if not professing to using an Agile methodology, if unit tests, integration tests, refactoring, and research don't take up a significant amount of the software development schedule or there's no scheduling of a significant amount of time to communicate with customers; the team is inept.  In this day and age, I would hazard to say its downright felonious and fraudulent.

DotNetKicks Image

Becoming a Visual Studio Jedi Part 1

Becoming a Visual Studio 2008 (and often Visual Studio 2005) Jedi

In much the same grain as James' Resharper Jedi posts, I'm beginning a series of posts on becoming a Visual Studio Jedi.  It involves getting the most out of Visual Studio off-the-shelf, doing things as quickly as possible and with as little friction as possible.  I think it's useful for all users; but especially useful for those who are in situations where they can't install refactoring tools like Refactor Pro! or Resharper.

First, familiarize yourself with Sara's Visual Studio Tips blog; then subscribe to her blog.

I'll attempt to provide detail at a less granular level than Sara's blog (i.e. using a series of commands to perform a specific task); but I may overlap here and there

Take advantage of Auto-Hide
Like Jimmy Bogard and Jeffery Palermo, I have my Visual Studio UI very lean. 99% of the time, I'm working in code.  The Solution Explorer (SE), Properties, Output, etc are auto-hide panes.  When I need to use them I hover the mouse over the tab to make them visible, do what I need to do with them, then get back to the code.  The Code Editor is the only window that isn't auto-hide or floating.

Navigate find results via keyboard
Whenever anything is displayed in a find results window, you can iterate each item in the list via a keystroke.  The default C# keyboard map had F8 and Shift+F8 as the shortcuts for next and previous.

For example:

  1. Press Ctrl+Shift+F to bring up the Find in Files form.
  2. Enter "TODO\:.*refactor" in the "Find what" text box.
  3. Ensure Match case, Match whole word are unchecked.
  4. Ensure Use is checked and has Regular expressions selected.
  5. Press Alt+F to search.

A Find Results window is displayed that shows the results of the search.

  • F8 goes to the first result.
  • Pressing F8 again goes to the next.
  • Pressing Shift+F8 goes to the previous result.

See also:
http://blogs.msdn.com/saraford/archive/2008/04/18/did-you-know-you-can-use-f8-and-shift-f8-to-navigate-among-errors-in-the-output-window.aspx
http://blogs.msdn.com/saraford/archive/2007/11/08/did-you-know-how-to-use-f8-to-navigate-the-find-results-window.aspx
http://blogs.msdn.com/saraford/archive/2005/03/30/403887.aspx

F8 and Shift+F8 work for most lists like Find Results 1, Find Results 2, Error List, Output:Build, etc.

File name extensions when adding classes
Do you find your self selecting text in the file name when you use the Add Class wizard?  Or, do you always type ".cs" at the end of your file name?  You may be happy to know you don't have to do that.  Simply invoke the Add Class wizard and type the name of the class.  The wizard adds the missing .cs for you.  For example:
Press Alt+P, C
Enter "MyNewClass"
Press Enter
A file MyNewClass.cs is added to your project and it contains class named "MyNewClass".

Consider a Custom toolbar

There's generally only handful of toolbar buttons that you might need, especially if you're a keyboard user like me.  There's some things that simply don't have a default keyboard mapping.  Another good reason for having a custom toolbar item with only the buttons you use is if you often change the size of your Visual Studio window.  The default layout has two or more toolbars (depending on the edition and any add-ins you have installed).  You can carefully position those toolbars so they may take up one or two lines; but when you then shrink the size of your window the get wrapped and they won't restore if you expand the size of your window.  Having a single toolbar means this wrapping of toolbars can never happen.

Export Settings

Once you get your UI the way you want it, you can actually save the layout. 

  1. Click on Tools\Import and Export Settings.
  2. Select Export selected environment settings.

This is really handy if you get into low-resource situations (like the application you're developing or its framework uses up too many GDI handles and Visual Studio can't allocate a handle to display a toolbar or a frame.  When this happens Visual Studio actually turns off those GUI elements; when you close and restart those panes/frames are no longer displayed by default.)

DotNetKicks Image

Trials and Tribulations of DataGridView, Column Selections, and Sorting

I had to implement some custom sorting in a DataGridView recently.  Essentially, the stakeholders wanted full column selection (like Excel) while still having the ability to sort the data based on a particular column.

This particular DataGridView is data-bound.  DataGridView offers the Sort(DataGridViewColumn, ListSortDirection) method to perform this.  Nice and easy I thought: I’ll set the SelectionMode to DataGridViewSelectionMode.ColumnHeaderSelect and simply call Sort with the selected column.

Well, much to my chagrin this had the side effect of making that column look selected all the time.  No matter where else I clicked, that recently sorted column looked selected (SelectedColumns had a count of zero).  And to add insult to injury, when I control-clicked that column (thinking it was selected) to unselected it, it caused a NullReferenceException deep in the framework.

Suffice it to say, this makes it very difficult to sort by columns in DataGridView without using the built-in sort-column-when-header-is-clicked mode.

What I’m now attempting to do is to unselect the column before sorting it.  This, in itself, is not trivial either; there’s no public method to select or deselect a column in the DataGridView.  I’ve had to create a new DataGridView derivative and call the protected method SetSelectedColumnCore.  A few hoops…

I’ve logged a couple of issues on Microsoft Connect about these problems.  The first is about ctrl-clicking the column and getting an exception:  https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=363623 The second is about the visual state of the column remaining “selected”: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=363623 Attached to this post you will find the project referenced by the two Connect issues.

[Update: I've currently only tried this with a .NET 2.0 project in Visual Studio 2008 SP1; if you find this problem occurs in Visual 2008 RTM, please comment.]

[Update: I overlooked the DataGridViewColumn.Select property, so there's no need to derive from DataGridView]

DotNetKicks Image

Drag and drop of control selections onto forms designer toolbox

A while back I blogged about the ability we have in Visual Studio to select text in a text editor and drag it onto the toolbox.  Once on the toolbox you could drag those items back into the text editor to effectively “paste” frequently needed snippets of code into other text files.

Imagine my surprise when we didn’t have this ability in the forms designer.  When writing code, it’s a bit specious to want to have multiple copies of hard-coded snippets of code (DRY should come to mind).  But, for forms, the only alternative is to create user controls to contain commonly-used control groups.  User controls is very heavy weight and basically becomes unusable when talking about simple groups of buttons.  For example, “OK” and “Cancel” buttons.

So, as a result, I’ve logged a suggestion on Microsoft Connect suggesting this ability be added to Visual Studio.

If you want to see the potential of a feature like this, see http://machine.nukeation.com/preview.html

DotNetKicks Image

Location of unit tests.


I had a short  conversation at Alt.Net Canada about the location of unit tests.  I personally tend towards a distinct unit test project.  But, I deal with mostly commercial, off-the-shelf (COTS) projects where I simply can't ship code like that.  I also don't want to wire-off the unit test via #if because I would then be shipping something different than that which was tested.

From an enterprise application point of view, this is different.  I would have no problem including the unit tests within their respective project as production code

DotNetKicks Image

The winds of change are blowing

The essence of ALT.NET, or at least the essence that people made use of, was that it was a venue for improving one's skills.  There has always been an undercurrent of other agendas there; but they never really took root.

The problem with the ALT.NET moniker was it isolates it from most of the industry--it was an island of .NET practitioners.  This basically flicked its thumb at the other communities--other communities that propagated some of the guidance that ALT.NET was trying to proliferate.

In the very spirit of continuous improvement it seems that ALT.NET is attempting to evolve and the ALT.NET conferences may continue (at least for a period of time, until the next kaikaku) as Kaizen conference.

Kaizen is a much more appropriate name for what people use and get out of the ALT.NET conferences.  I just hope this change doesn't cause division, distrust and dissent (for lack of a better word).

I've said from the beginning that "ALT.NET" had some flaws as a name.  I hope Kaizen will continue to give the same people the ability to improve, while embracing more.

DotNetKicks Image

Extra Features: One of the Lean 7 Wastes of Software

Derik Whittaker recently blogged about how writing unused code is one of the Lean 7 Wastes of Software.  Mary Poppendieck calls this "Extra Features" and has a one-to-one association to overproduction in manufacturing. 

In Manufacturing it has different caveats: if you overproduce something you have to have somewhere to store it until its sold.  What do you do when you don't have the space to store it?  If you have the space, it's not too much of an issue; you just tuck it away; but you still need people to move it, manage the space, manage the responsibilities around moving/storage, etc. etc.

With Lean Software, there is still technically a storage issue (VCS, disk space, etc.).  The real issue with extra features is that no one is using them. In the best case this means you're consuming expensive resources that aren't directly increasing revenue.  Worst case you're also impacting the usability (and thus the sell-ability) of the software.  If the extra features are something that the vendor hopes to be used in the future; then you've increased the time between implementation and fixing bugs.  Unit testing aside, when customers log bugs against the software regarding something implement 6 months ago, you've increased the cost of fixing the bug exponentially as time goes on.  This is the philosophy behind TDD, that unit tests find bugs as soon as possible (~build time, depending you your setup).

From an Agile standpoint, extra features mean you're giving the user something they didn't want.  This means you're not listening to your customer and don't have a relationship built on communication.  In Agile, it's a tenet to build prototype code based ideas you've inferred from communication with the customer.  This isn't extra features, this is the feedback process.  It's fine to propose a feature to the user in the form of a prototype; but if they don't want it, it doesn't go into the release.

Extra features is technical debt that you'll have to pay for eventually.

DotNetKicks Image

Law of Reversibility of Attributes

I've come up with a simple law called Law of Reversability of Attributes.  It’s based on the physics law of a similar name.  Basically what the law means is that the inverse of a transformation should result in a return to the original state.

The Law of Reversibility of Attributes is defined as:

For a given state of an object; when a attribute’s value is changed, the inverse of that value, when applied to that attribute, will result in the object returning to its original state.

I say “attribute” rather than “property” to encompass methods that imply setting of attributes.  So, for example

            myObject.BooleanValue = !myObject.BooleanValue;
            myObject.BooleanValue = !myObject.BooleanValue;

and

            myObject.SetBooleanValue(!myObject.GetBooleanValue());
            myObject.SetBooleanValue(!myObject.BooleanValue());

means myObject will be in the same state after the second line of code than it was before the first line of code.

[UPDATE: interestingly, after I wrote this post--which was delay-published--Bill Wagner wrote a great article on a very similar topic in Visual Studio Magazine]

DotNetKicks Image

DataGridViewColumn.Frozen

DataGridViewColumn.Frozen is documented as "When a column is frozen, all the columns to its left (or to its right in right-to-left languages) are frozen as well."

Which is nice until you think of the consequences.  The consequences being that freezing a column and all columns to the left is performed with a single assignment of true to the Frozen property of that column; but to unfreeze is not the opposite (a assignment of false to the Frozen property of that column).  No, you must unfreeze each of those columns to the left.  This can be done by manually unfreezing each column, or by unfreezing column 0.

This means that column.Frozen = false is not the opposite of column.Frozen = true—resulting in unbalanced reversible side-effects.

Neither of the techniques to “unfreeze” the column that was frozen is intuitive; but unfortunately this interface is not "intention revealing".  You’re not just setting the Frozen property of a column, you’re setting the frozen property of that column and all the columns to the left.

Greg Young recently commented (I don’t remember where) about writing classes without any properties.  This approach would have helped here.  What Greg is alluding to is to recognize behaviour rather than shape.  Freezing the current column and all columns to the left is a behaviour, not an attribute; and it should be modeled as a method rather than a property.

At any rate, if you have a DataGridView on your form, you may be interested in using these methods instead:

        private void FreezeAtColumn(int value)
        {
            dataGridView.Columns[value].Frozen = true;
        }
 
        private void UnfreezeColumns()
        {
            dataGridView.Columns[0].Frozen = false;
        }
DotNetKicks Image

Microsoft Knowledge Base Themes

Does the look of Microsoft Knowledge Base articles bore you?  Well, you can spruce them up with a Zune or X-Box theme.

For example, http://support.microsoft.com/kb/312906, looks like this:

image 

By simply adding ?sd=xbox or ?sd=zune to the end of the URL, you can change it to look like this

image 

and this

image

… respectively.

For all I know, there’s many more valid sd values.  If you know of any, post ‘em.
DotNetKicks Image

ITSWITCH #1: Answer

Last post I detailed some code that may or may not have something wrong in it.  If you thought InitializeOne and IntializeTwo are semantically identical (e.g. they differ only by performance), you'd be wrong.

If you simply ran the code, you'd be able to guess where the problem is.  To understand what's causing the problem.  Let's look at how C# effectively implements the two loops.

InitializeOne is essentially equivalent to

        private class PrivateDelegateHelper
        {
            public String Value { get; set; }
            public void Method()
            {
                TestClass.ProcessText(Value);
            }
        }
 
        public void InitializeThree(String[] strings)
        {
            delegates = new List<MethodInvoker>(strings.Length);
            MethodInvoker cachedAnonymousDelegate = null;
            PrivateDelegateHelper privateDelegateHelper = new PrivateDelegateHelper();
            String[] copyOfStrings = strings;
            for(int i = 0; i < copyOfStrings.Length; ++i)
            {
                privateDelegateHelper.Value = copyOfStrings;
                if (cachedAnonymousDelegate == null)
                {
                    cachedAnonymousDelegate = new MethodInvoker(privateDelegateHelper.Method);
                }
                delegates.Add(cachedAnonymousDelegate);
            }
        }

Now it's obvious, right?

For those you don't want to read all the code, the problem is that only one PrivateDelegateHelper object is instantiated and its value property is set in each iteration of the loop.  Because the delegates aren't run until sometime after the loop, they're all run with the last value of the string array as their argument.

The technical term for what we've implemented here is a closure.  If you're using Resharper 4.x, you would have noticed a warning "Access to modified closure":

 

...which is attempting to tell you that the closure (the delegate and cached bound variables) has changed (in this case one of the bound variables has changed between the creation of a closure and another and out expected output is effected).

By the way, you can get the same thing with C# 3+ with lambdas (i.e. you can also write closures with lambdas):

        public void InitializeOne(String[] strings)
        {
            delegates = new List<MethodInvoker>(strings.Length);
            for (int i = 0; i < strings.Length; ++i)
            {
                String value = strings;
                delegates.Add(() => ProcessText(value));
            }
        }
 
        public void InitializeTwo(String[] strings)
        {
            delegates = new List<MethodInvoker>(strings.Length);
            foreach(String value in strings)
            {
                delegates.Add(() => ProcessText(value));
            }
        }
Posted by PeterRitchie | with no comments
Filed under: ,