• Kirill Osenkov

    New CodePlex project: a simple Undo/Redo framework

    • 57 Comments

    I just created a new CodePlex project: http://undo.codeplex.com

    What

    It's a simple framework to add Undo/Redo functionality to your applications, based on the classical Command design pattern. It supports merging actions, nested transactions, delayed execution (execution on top-level transaction commit) and possible non-linear undo history (where you can have a choice of multiple actions to redo).

    The status of the project is Stable (released). I might add more stuff to it later, but right now it fully satisfies my needs. It's implemented in C# 3.0 (Visual Studio 2008) and I can build it for both desktop and Silverlight. The release has both binaries.

    Existing Undo/Redo implementations

    I do realize that my project is the reinvention of the wheel at its purest, existing implementations being most notably:

    However I already have three projects that essentially share the exact same source code, so I decided that it would be good to at least extract this code into a reusable component, so perhaps not only me but someone else might find it useful too.

    It's open-source and on CodePlex, so I also have a chance of benefiting from it if someone contributes to it :)

    History

    It all started in 2003 when I first added Undo/Redo support to the application that I was developing at that time. I followed the classical Command design pattern, together with Composite (for nested transactions) and Strategy (for plugging various, possibly non-linear undo buffers).

    Then I needed Undo/Redo for my thesis, so I just took the source code and improved it a little bit. Then I started the Live Geometry project, took the same code and improved it there a little bit, fixing a couple of bugs. Now the mess is over, and I'm finally putting the code in one place :)

    A good example of where this framework is used is the Live Geometry project (http://livegeometry.codeplex.com). It defines several actions such as AddFigureAction, RemoveFigureAction, MoveAction and SetPropertyAction.

    Actions

    Every action encapsulates a change to your domain model. The process of preparing the action is explicitly separated from executing it. The execution of an action might come at a much later stage after it's been prepared and scheduled.

    Any action implements IAction and essentially provides two methods: one for actually doing the stuff, and another for undoing it.

    /// <summary>
    /// Encapsulates a user action (actually two actions: Do and Undo)
    /// Can be anything.
    /// You can give your implementation any information it needs to be able to
    /// execute and rollback what it needs.
    /// </summary>
    public interface IAction
    {
        /// <summary>
        /// Apply changes encapsulated by this object.
        /// </summary>
        void Execute();
    
        /// <summary>
        /// Undo changes made by a previous Execute call.
        /// </summary>
        void UnExecute();
    
        /// <summary>
        /// For most Actions, CanExecute is true when ExecuteCount = 0 (not yet executed)
        /// and false when ExecuteCount = 1 (already executed once)
        /// </summary>
        /// <returns>true if an encapsulated action can be applied</returns>
        bool CanExecute();
    
        /// <returns>true if an action was already executed and can be undone</returns>
        bool CanUnExecute();
    
        /// <summary>
        /// Attempts to take a new incoming action and instead of recording that one
        /// as a new action, just modify the current one so that it's summary effect is 
        /// a combination of both.
        /// </summary>
        /// <param name="followingAction"></param>
        /// <returns>true if the action agreed to merge, false if we want the followingAction
        /// to be tracked separately</returns>
        bool TryToMerge(IAction followingAction);
    
        /// <summary>
        /// Defines if the action can be merged with the previous one in the Undo buffer
        /// This is useful for long chains of consecutive operations of the same type,
        /// e.g. dragging something or typing some text
        /// </summary>
        bool AllowToMergeWithPrevious { get; set; }
    }

    Both methods share the same data required by the action implementation and are supplied when you create an action instance.

    ActionManager

    Your domain model (business objects) will likely have an instance of ActionManager that keeps track of the undo/redo buffer and provides the RecordAction(IAction) method. This method adds an action to the buffer and executes it. And then you have ActionManager.Undo(), ActionManager.Redo(), CanUndo(), CanRedo() and some more stuff.

    As a rule, the thing that works for me is that I generally have two APIs: one that is public and lazy (i.e. it just creates an action and adds it to the buffer), and the other which is internal and eager, that does the actual work. Action implementation just calls into the eager API, while the public API is lazy and creates actions transparently for the consumer.

    History

    Right now I only have a SimpleHistory. Instead of having two stacks, I have a state machine, where Undo goes to the previous state and Redo goes to the next state, if available. Each graph edge stores an action (implementation of IAction). As the current state transitions along the graph edge, IAction.Execute or UnExecute is being called, depending on the direction in which we go (there is a logical "left" and "right" in this graph, which kind of represents "future" and "past").

     

    image

    It's possible for this linked list to become a tree, where you try something out (way1), don't like it, undo, try something else (way2), like it even less, undo, and choose to go back and redo way1. However this is not implemented yet.

    Transactions

    Transactions are groups of actions viewed as a single action (see Composite design pattern).

    Here's a typical usage of a transaction:

    public void Add(IEnumerable<IFigure> figures)
    {
        using (Transaction.Create(ActionManager))
        {
            figures.ForEach(Add);
        }
    }

    If an action is recorded while a transaction is open (inside the using statement), it will be added to the transaction and executed only when the top-level transaction commits. This effectively delays all the lazy public API calls in the using statement until the transaction commits. You can specify that the actions are not delayed, but executed immediately - there is a corresponding overload of Transaction.Create specifically for that purpose.

    Note that you can "misuse" this framework for purposes other than Undo/Redo: one prominent example is navigation with back/forward.

    Update: I just posted some samples for the Undo Framework: http://blogs.msdn.com/kirillosenkov/archive/2009/07/02/samples-for-the-undo-framework.aspx

  • Kirill Osenkov

    Interview question

    • 47 Comments

    Here’s a nice simple interview question:

    In a given .NET string, assume there are line breaks in standard \r\n form (basically Environment.NewLine).

    Write a method that inserts a space between two consecutive line breaks to separate any two line breaks from each other.

    Also, anyone venture a guess what is a practical application for such a method?

  • Kirill Osenkov

    How to debug crashes and hangs

    • 38 Comments

    At my job on the C# IDE QA team I've learned some useful things about debugging in Visual Studio, which I'd like to summarize in this post. Although the screenshots were made using Visual Studio 2008 SP1, this pretty much applies to other versions of VS as well.

    Rich debugging support

    When you develop your C# application and hit F5, the target process (your program) gets started, and then the Visual Studio process attaches the debugger to the process where your code is running. This way, you can break into the debugger and VS will provide you with all sorts of rich debugging support - current statement highlighting, call stack, watches, locals, immediate window, Edit-and-Continue and so on.

    More importantly, if your application throws an exception or crashes, the debugger will intercept that and provide your with all the information about the exception.

    As a side note, in Visual Studio there is a way to run your code without attaching the debugger - the shortcut is Ctrl+F5. Try throwing an exception in your code when using F5 and Ctrl+F5 to feel the difference.

    throw null;

    By the way, my favorite way to artificially throw exceptions is throw null; I just love the fact that it throws a NullReferenceException because it can't find the exception object and nevertheless does exactly what I want it to do :)

    Crashes and the Watson dialog

    What if a program crashes or throws an exception, which you don't have source code for? Moreover, you didn't start the program using F5, but the operating system launched the process. I remember that before coming to Microsoft, the only thing I could do about some application crashing was to express my disappointment about the fact (usually in Russian). Now I don't feel helpless anymore, because I've learned a couple of tricks. As an example for this we'll crash Visual Studio itself and then debug the crash.

    How to crash Visual Studio?

    Viacheslav Ivanov reported an interesting crashing bug in our language service recently. Save all your work and then paste this code in a C# Console Application and change 'object' to 'int':

    using System;
    
    static class Program
    {
        static void Main()
        {
            ITest<object> test;
            test.Test((object /* and now change the argument type to "int" */ i) => { });
        }
    }
    
    public interface ITest<T> { }
    
    public static class Extensions
    {
        public static void Test<T, I>(this ITest<T> test, Action<ITest<I>> action) { }
    }

    What you will see is the Watson dialog:

    image

    Given this chance, I'd highly recommend everyone to click "Send Error Report" if you ever see this dialog for Visual Studio. Many people "Don't Send" and frankly I don't understand why not. There is no personal information being sent, and we don't want your personal information anyway, honest. What we want is a call-stack and minidump, if possible, so if you want us to fix the product to make it more stable in the future, you will greatly help us if you send us the Error Report. By the way, we usually fix most (if not all) crashes that come in through this dialog, so the chances that we'll fix the crash you report using the dialog are actually pretty high. For example, we've already fixed the bug mentioned above and it works just fine in current builds.

    Attaching a debugger

    So what can you do if an application crashes or hangs? You can attach the debugger to a running process, even if it has already crashed. The code is still being executed (the main thread of the crashed application is usually pumping messages for the error dialog). You can either choose "Debug" on the Watson dialog, or (what I usually do) is start a new instance of Visual Studio myself and attach to the process manually, without dismissing the Watson dialog.

    Note: if the debuggee process crashes and you attach the debugger after the fact, you'll have to manually break into the debugger by pushing the "Pause" button. If the debugger was already attached at the moment of the crash, then it will offer you to break or continue.

    You can attach the Visual Studio debugger to a running process by choosing Tools | Attach To Process (Ctrl+Alt+P):

    image

    You will see the Attach to process dialog:

    image Interesting things to note here are the Attach to: selection. Since Visual Studio is a mixed-mode managed/native application, to get call stacks for both managed and native parts, you'd want to attach to both of them (by clicking Select...):

    image

    If you select both Managed and Native, you'll get richer debugging information about your callstacks - this is recommended.

    Note: if you want to enable mixed-mode debugging (managed+native) for the application that you have source code for, go to project properties of the startup project, and on the Debug tag select "Enable unmanaged code debugging". Then the debugger will automatically attach using mixed-mode.

    Finally, select the process from the list which you'd like to attach to (in our example, it will be devenv.exe) and click Attach. Notice that the process of the debugger itself is not shown in the list, that's why you don't see two devenv.exe in the list.

    Remote Debugging

    What many people don't know is that VS can be used to debug a process running on another machine on the network. To do this, you just need to start the Visual Studio Remote Debugging Monitor on the same machine with the process you want to debug:

    image

    The remote debugging monitor will listen to debugger connections on the other machine and you'll be able to attach the debugger using the Transport and Qualifier fields on the Attach to process dialog:

    image

    You can find more detailed information about Remote Debugging in MSDN and on the internet.

    Set Enable Just My Code to false

    One very important option in Visual Studio is "Enable Just My Code", which is set to true by default. To be able to see more information on the callstacks instead of just "Non-user code", you need to go to Tools | Options and disable this option:

    image

    I usually do this right after I install Visual Studio, so that I can always debug into "not my code".

    Other interesting options on this page are:

    • Enable .NET Framework source stepping - in case you'd like to step into the .NET framework source code
    • Enable Source Server support
    • Step over properties and operators (Managed only) - won't step in to property getters, operators, etc. - this is new in VS 2008 SP1
    • Require source files to exactly match the original version - in case you don't have the source files for the exact .pdb symbol file, but still have a close version of the source code

    Break on first chance exceptions

    One very useful option in the debugger is the ability to break whenever a first-chance exception is being thrown. A first-chance exception is an exception that might be caught by the program itself later in some surrounding catch block. First-chance exceptions are usually non-fatal and handled (or swallowed) by the user, so they might not even be visible to the end user during normal execution. However, if a first-chance exception is not handled in the code and bubbles up to the CLR/OS, then it becomes a crash.

    So, to break on first-chance exceptions, you can go to Debug | Exceptions to invoke the Exceptions dialog:

    image

    Here you can put a checkmark on Common Language Runtime Exceptions for the debugger to break every time a managed exception is thrown. This way you will see more hidden exceptions, some of them originating deep in the .NET framework class library. Sometimes there are so much first-chance exceptions that you can become overwhelmed, but they are incredibly useful to get to the root cause of the problem, because the debugger will show exactly where the exception originated preserving the original surrounding context. Another great advantage of breaking on first-chance exceptions is that the call stack is not unwound yet and the problem frame is still on the stack.

    Debugging tool windows

    OK, so now that we know how to attach a debugger and how to set the debugger options, let's see what happens after we've attached a debugger. For our exercise, you can open two instances of Visual Studio, attach the second instance's debugger to the first one, and then crash the first one using the lambda-expression crash code above. Instead of the Watson dialog on the debuggee process, you will see the following window in the debugger:

    image

    Now you have the chance to break and see where the exception happened. Continue is useful if the exception is actually a first-chance exception and you'd like to pass it on to user code to handle it. Let's hit Break and examine what tool windows are available under debugger.

    Processes window

    All the debugger windows are available from menu Debug | Windows. The Processes window shows the list of processes that the debugger is currently attached to. A nice trick is that you can actually attach to multiple processes at the same time. Then you can use this window to switch the "current" debuggee process and all other tool windows will update to show the content of the "current" process.

    image

    Note: on our team, we use this window a lot, because our tests run out-of-process. Our test process starts Visual Studio in a separate process and automates it using DTE, remoting and other technologies. Once there is a failure in the test, it's useful to attach to both the test process and the Visual Studio process under test. The most fun part is when I was debugging a crash in the debugger, and attached the debugger to the debugger process that is attached to some other process. Now if the debugger debugger crashes on you on the same bug, then you're in trouble ;) Sometimes I definitely should blog more about the fun debugging stories from my day-to-day job. But I digress.

    Threads

    As we all know, processes have multiple threads. If you break into a debuggee process, you will most likely end up with a list of threads that were active at the moment when you did break. Main thread is the green one - this is the UI thread of your application (in our example, Visual Studio). Main thread executes the application message loop, and is pumping the windows messages for the application's UI. If a message box or a dialog is shown, you will see this dialog's message loop on the main thread.

    image

    To switch threads, double-click the thread name that you're interested in. In most of the cases you'll be interested in the main thread. But if you start your own threads, give them a name so that they are easy to find in the threads list.

    Call stack

    Every thread has a call stack. Call stack is probably the most important thing you'd like to know about a crash - what was the sequence of function calls that lead to a crash? If the program is hanging, you'd like to know what function is it hanging in and how did it get there. Oftentimes by just glancing at a callstack you immediately know what's going on. "Is this callstack familiar?" or "Who is on the callstack?" is probably the question we ask most often during the bug triage process.

    Anyway, here's the call stack window:

    image

    In our example we see that the C# language service module is on the stack (.dlls and .exes are called "modules" in the debugging world).

    However instead of function names from cslangsvc.dll we see the addresses of the procedures in memory. This is because the symbols for the cslangsvc.dll module are not loaded. We'll look into how to load symbols in a moment.

    Modules

    The Modules window shows a list of .dlls and .exes loaded into the debuggee process:

    image

    There are multiple ways to load symbols for a given module. You can right-click on a module for a list of options:

    image

    Symbols for modules are stored in .pdb files and are produced with every debug build of the binary. pdb files contain mapping from compiled binaries back to the original source code, so that the debugger can display rich information (function names, source code locations, etc.) for the binary being debugged. Without symbols, debugging is only possible at the assembly level and registers window, you can't map the binaries back to the source code.

    Symbols

    A very useful dialog is the Tools | Options | Debugging | Symbols:

    image

    Here you can set paths where to look for the .pdb files. Normally, the .pdb files will be directly next to the binaries, in which case they are usually found and loaded automatically. Loading symbols takes some time, so Visual Studio supports caching symbol files to some directory. Also, if you don't want all the symbols for all the binaries loaded (it can take a while), you can check the checkbox "Search the above locations only when symbols are loaded manually". Load symbols from Microsoft symbol servers provides symbols for Microsoft products, such as Windows and Visual Studio. You can load symbols from here, or also from the Modules or Call Stack windows, by right-clicking on a module and choosing Load Symbols From. Since we're debugging into Visual Studio, the symbols are located on the Microsoft Symbols servers:

    image

    When we load public symbols, the following little dialog is showing:

    image

    After we've loaded the symbols for cslangsvc.dll we notice that the Call Stack window is now much more informative:

    image

    Given this call stack, anyone of our developers will now easily be able to pinpoint the problem. In our example we see that the problem happens when we try to show the Smart Tag for the Generate Method refactoring:

    image

    As you see, there are more modules for which the symbols haven't been loaded yet. You can load the symbols for those modules by right-clicking their stack frame and choosing Load Symbols From. Loading all the symbols is usually recommended for more detailed information.

    That is why the call stack is so precious during bug reports. To save the call stack, you can Ctrl+A and Ctrl+C to copy all the stack into the clipboard. When you click Send Error Report in the Watson dialog, the call stack is included in the error report.

    Also you see that the call stack is not very useful without the symbols - it's the symbols + the callstack that provide rich information about the crash.

    Minidump

    Another very useful information that you can provide about the crashed process is the memory dump (heap dump, minidump) - this is basically a snapshot of the memory state of the crashed process. To create a minidump, go to Debug | Save Dump As. Visual Studio will offer you to save the dump to a location on disk, and an option to just save the Minidump or Minidump with Heap:

    image

    Minidump with Heap will save more information than just the minidump, but will take a whole lot more disk space (for Visual Studio - possibly hundreds of megabytes - depending on the process working set size during the crash).

    Those are the three components that we usually send to our developers during crash bug reporting:

    1. Call stack
    2. Symbols
    3. Minidump with heap

    In most cases, they are able to understand the problem given this information. A list of repro steps is usually even better, because they can reproduce the problem themselves and enable first-chance exceptions to break early into the problem area.

    Debugging hangs

    If an application hangs, you can attach the debugger to it and hit break to see what thread and what call stack blocks execution. Usually looking at the call stack can give you some clues as to what is hanging the application. Debugging hangs is no different than debugging crashes.

    Microsoft shares customer pain

    Finally, I'd recommend everyone to watch this video:

    Conclusion

    In this post, I've talked about some things worth knowing for effective debugging sessions:

    • Turning off "Enable just my code"
    • Attaching the debugger using Tools | Attach To Process
    • Selecting Managed, Native for mixed-mode debugging or Enable unmanaged code debugging
    • Attaching to multiple processes
    • Selecting processes and threads
    • Breaking on first-chance exceptions using the Debug | Exceptions dialog
    • Picking the right thread
    • Loading symbols
    • Viewing the call stack
    • Saving the minidump file

    Do let me know if you have feedback or corrections about this information.

    kick it on DotNetKicks.com
  • Kirill Osenkov

    Call Hierarchy Navigation in Visual Studio 2010

    • 30 Comments

    We're currently designing a new IDE feature named Call Hierarchy. Essentially, it allows you to find places where a given method is called, which is similar to how Find All References currently works. However, unlike Find All References, the Call Hierarchy feature provides more deep understanding and more detailed information about calls.

    Invocation

    You can invoke the Call Hierarchy toolwindow by right-clicking on a method, property or constructor name in the code editor and choosing View Call Hierarchy from the context menu:

    image

    Tool window

    A toolwindow will appear docked on the bottom of the Visual Studio window:

    image

    You can expand the node for the method to see information about it: incoming calls to the method ("Calls To") and outgoing calls ("Calls From"):

    image

    Here's how it works. A method (or a property, or a constructor) is displayed as a root in the treeview. You can expand the node to get a list of "search categories" - things you want to find. Four search categories are currently supported:

    1. Calls To - "incoming" calls to this member
    2. Calls From - "outgoing" calls mentioned in this member's body
    3. Overrides - available only for abstract or virtual members
    4. Implements - finds places where an interface member is implemented

    When you expand a search node (such as Calls To 'GetCallableMethods'), a solution-wide search is started in the background and the results appear under the Calls To folder. You can click on a result, and the details will appear in the Details list view on the right hand side.

    The Details list view shows all the exact call sites and locations in code where GetCallableMethods is called from GenerateXsdForComplexTypes. We see that the method is being called only once, the line of code is shown, as well as file name and position in the file. Double-clicking on that call site will navigate to it in the code editor.

    The advantages of Call Hierarchy compared to Find All References is that it allows you to explore and drill deep multiple levels into the call graph (find caller's caller etc.) Also, Call Hierarchy has deeper and more fine-granular understanding of the source code - while Find All References just finds the symbols, Call Hierarchy differentiates abstract and virtual methods, interface implementations, actual calls from delegate creation expressions, etc. Also it works like a scratch-pad: you can add any member as another root-level item in the call hierarchy tool window and have several members displayed there at once. Finally, the Details Pane given information about the concrete call sites, if a method is being called several times in the body of the calling method.

    Toolbar

    In the toolbar you can select the scope of the search: search in currently opened file only, current project or the entire solution.

    Refresh button re-fills the treeview in case the original source code was modified.

    If a root node of the treeview is selected, the "Delete Root" button will remove it from the treeview. You can add any member as a new root in the treeview by right-clicking on it in the context menu:

    image

    or adding it from the source code as described in the beginning.

    Finally, the Toggle Details Pane button shows or hides the details pane.

    Some design issues and implementation details

    Although the feature is already implemented and if you have the Visual Studio 2010 CTP, you can already play with Call Hierarchy, we're still not quite happy with the current UI design, usability and the user experience.

    For example, one issue that we're seeing is that it takes 2 mouseclicks and 2 mousemoves to invoke the Find All References search, but it takes 4 mouseclicks and 4 mousemoves to get the callers list for a given method (1 click - menu invocation, 1 click - menu item selection, 1 click - expand the treeview node for the method, 1 click - expand the "Calls To" folder). Although the search itself will be slightly faster than Find All References, the perceived complexity of invoking the feature is something we definitely want to improve. We want this feature to be at least as good and usable as Find All References, but also provide additional benefits, otherwise people will just not use the feature and continue using Find All References.

    I think I'll stop for now and see what kind of feedback you guys might have about this. In the next blog post I plan to share more of our current thinking and what we'd like to change. For now, I'd be really interested to know what you think and if you have any suggestions or ideas. Now it's not too late, and we can change the feature based on your feedback.

  • Kirill Osenkov

    5 min. screencast: Live Geometry overview

    • 28 Comments

    Microsoft sponsored a usability study for my side project Live Geometry, and I have to say, it was awesome. It was a lot of fun watching the participants using the software and I got a ton of great and useful feedback.

    I have to confess, I didn’t realize that it’s not obvious how to use Live Geometry (especially if you’ve never seen it before). Since I was the one who developed the software, I subconsciously assumed that it’s all intiutive and trivial. Well guess what, it turns out to be not the case. I am not the end user. Things that are obvious for me, might not be obvious for others.

    So I developed a plan on how to make things better. There are two ways: improving User Experience and investing in User Education. The former will be a slow and gradual process of me designing the features and the UI, fixing bugs, reworking the UI and thinking through UI details.

    Today I’ll start approaching the task of User Education and present a 5 min. screencast – a brief overview of the Live Geometry software and its possibilities (Hint: double-click the video for fullscreen viewing):

    Get Microsoft Silverlight

    You can also download the .wmv file (15 MB).

    More documentation will follow later, but this should at least give a quick start and give you an idea of how things work.

    Any feedback is welcome!

  • Kirill Osenkov

    Naming Roslyn concepts

    • 28 Comments

    We have a rather central component in Roslyn and we’re looking how to name it best. I’d like to gather some advice and opinions that could potentially help us find a good name.

    I am intentionally not mentioning what is it called right now. Instead, I’m going to describe it. If you recognize this component from the Roslyn CTPs, please don’t name it in the comments so as not to accidentally drive others towards its current name, which we believe is overused in our domain already.

    Roslyn analyzes code. Code is most often organized into solutions, projects and documents. Primarily we use three types to model source code: Solution, Project and Document. A Solution has a set of Projects, a Project has a set of Documents. These form an immutable tree that captures a snapshot of a source code tree at a moment in time. This data structure only captures the information interesting to the compiler, it’s not an MSBuild or a project system concept. When the user edits the text of a document in the editor, adds a new project in Visual Studio or otherwise modifies code, a new immutable snapshot of the entire Solution is created. This is implemented using efficient immutable data structures that reuse most of the data between the snapshots. This way if an analysis was in progress while the user changed code, the analysis can continue on it’s own snapshot safely knowing that the snapshot will never change. Also we can utilize multiple cores for fast, safe, lock-free analysis.

    Now, the concept we’re looking to name is something that has a CurrentSolution property that points to the latest snapshot of the solution data structure. It can listen to changes in user’s source code, build a new Solution snapshot to reflect those changes, and finally update the CurrentSolution property to point to the latest snapshot. This concept also has an event that our features can listen to to update themselves when the current solution has changed.

    An environment that is hosting Roslyn (say the Visual Studio project system) is responsible for forwarding changes into this component such that it can recalculate the most up-to-date Solution and notify all observers.

    If a Roslyn feature, such as a refactoring, wants to modify the users code (e.g. generate a method), it doesn’t talk directly to the environment. Instead, it describes the changes it wants to apply to the current solution and forms a new, delta (diff) Solution, and hands it off to our component. Our component then takes this delta (changes) and sends it back to the host, asking the host to do whatever is necessary to actually apply these changes (edit a file, checkout a file from TFS, add a reference, etc.) The host then, after applying these changes will pipe the notifications back into our component to complete the circle.

    How do we name this component that is responsible for keeping the CurrentSolution up-to-date and ensures bidirectional communication of changes with the host environment?

    Thanks!

  • Kirill Osenkov

    Live Geometry with Silverlight 2

    • 24 Comments

    I'm happy to announce a project I started on CodePlex: http://codeplex.com/DynamicGeometry

    Live preview at: http://geometry.osenkov.com

    Dynamic geometry

    In a nutshell, it's an interactive designer for ruler-and-compass constructions - it lets you plot points, connect them with lines, construct circles, intersection points, parallel lines - everything that you usually do with "plain" geometry. But then the magic part comes in - you can drag the points and the entire construction is recalculated immediately - this is why they call it dynamic geometry. The way it works is the program doesn't store the coordinates of figures - instead, it stores the algorithm of their construction. Every time you move any of the points, the entire construction is being reconstructed on-the-fly given the new coordinates of the point using the algorithm stored in memory - that's why I like calling it "CAD with lazy evaluation".

    The actual program available online

    The application is deployed live at http://geometry.osenkov.com - you'll need Silverlight 2 Beta 2 to view this site. At first, the UI might seem not very intuitive for you - it takes a while to figure out how to use the toolbar and construct tools - but I hope an interested reader can tackle this challenge. The trick is to know the rules how the toolbox buttons work. Plotting points is easy - just select the point tool and click anywhere. Dragging points is easy too - select the arrow (cursor) tool and drag the points. Now, to construct a segment between two points, you select the segment tool, click (and release) the first point, and then click (and release) the second point. See, you specify that this segment depends on two points - every time you drag one of the points using the Drag tool, the segment will update itself accordingly.

    The source code is available online too!

    I used Visual Studio 2008, C# 3.0 and Silverlight 2 Beta 2. I have to say, those are awesome technologies and a pleasure to use (at least for me).

    I split the code into several projects. DynamicGeometry is a class library that provides a framework for defining figures and their interaction. My goal was to allow for extensibility - so that you can just plug in a new kind of a figure, and automatically consume all the centralized goodies - serialization, painting, dependency tracking, transaction system, interaction, etc. Now, the code for almost every figure fits in one screen of text - so I rarely have to scroll when editing these files. SilverlightDG is the Silverlight 2 front-end - UI. DG is the WPF front-end. I try to maintain two projects - WPF and Silverlight - to build from the same sources. So far so good :)

    Implementation details

    The project is still in its early Mickey Mouse stages and only some very basic functionality is there - however, there is already something that is worth noting:

    • an extensible type hierarchy to model geometric figures - all starts with IFigure and FigureBase
    • a State and Strategy pattern implementations to enable interactive mouse input from the user - different toolbox buttons provide different strategies to handle mouse input
    • a pretty decent transaction system, which enables nested transactions, Rollback, delayed execution, record/playback and, of course, unlimited Undo/Redo
    • a dependency tracking mechanism that allows to express dependencies between figures (i.e. a midpoint depends on two existing points) - I employ Topological Sorting to sort the figure DAG by the dependencies - we first want to recalculate the basic figures, and then their dependents
    • a toolbar that took me many painful hours to design - I highly respect UI designers and think that getting the UI right is more difficult than to implement the rest of the actual functionality. I hope I didn't do too bad, although I'm definitely not a great UI designer.

    Silverlight 2 Beta 2

    Most probably by this time you already know what Silverlight is all about - if not, www.silverlight.net is a great place to start. I personally believe that Silverlight is our liberation from the old web story and am very optimistic about this technology. While Silverlight 1.0 only allowed JavaScript programmability, Silverlight 2 gives you full experience of .NET and managed languages - C#, VB, IronPython, IronRuby and others (did I forget something?). I think that Silverlight's advantage over Adobe technologies is this rich programming model - the fact that you can use .NET and C# 3.0 for the web client just makes me so excited about this.

    Targeting both Silverlight and WPF from same source

    If you look closer at my source code, you will notice that I have two projects - the WPF one and the Silverlight one - including the same .cs files. Because WPF and Silverlight use different CLR and runtimes, the project format is incompatible - i.e. I can't include a Silverlight class library in a WPF application. Workaround is relatively easy - just create two separate .csproj files in the same folder, that reference the same sources - and you're fine.

    CodePlex

    By the way, CodePlex is a quite awesome site for open-source projects - it provides version control (I love TFS and think it's excellent), item tracking, forums, wiki, downloads, stats - all for free and without annoying ads. Codeplex is one of the products that still make me proud to be working at Microsoft.

    DG 1.0 - the inspiration

    The project that I'm describing in this post is actually based on an earlier one that I've implemented 7-8 years earlier - here's a blog post about my original dynamic geometry project: http://kirillosenkov.blogspot.com/2007/12/dg-10-free-dynamic-geometry-software.html

    I'd like to reach parity with the first version - however this is going to be tricky, because it has a lot of different goodies - from analytical expressions to ability to create hyperlinks and compose complex documents. Interestingly enough, I implemented DG 1.0 using VB6 - and though I think VB6 was an awesome environment at that time (I think it's Edit-and-Continue is still better than the one we have in Visual Studio 2008), I feel so much better and more comfortable using C# 3.0 - it just lets me express stuff about my program that I want to express in the way that I want.

    I hope some of you have found this interesting. I'd be happy to hear any feedback or advice on this.

    Thanks!

  • Kirill Osenkov

    Visual Studio 2010 Beta 2 Known Issues – Part 2

    • 23 Comments

    This post continues my unofficial list of known issues in VS 2010 Beta 2 (see Part 1). As we continue getting Beta 2 feedback and investigating issues, it's time for another update on the issues we've been seeing. Please keep in mind that due to the volume of the issues, I'm only mentioning the ones I was involved with or consider important.

    Crash during normal editor operation

    There is a rare situation where Beta 2 can crash during normal editing or viewing C# source code. Nevertheless, it happens often enough to become top 1 reported crash for C#.

    I'm very happy to say that we have identified the root cause and are working on a fix.

    Details: This is an extremely complex and hard to reproduce bug involving native code, threading, and working with Task Parallel Library from native code. The new C# IDE feature, Highlight References, is written in managed code and uses TPL (Task Parallel Library) to calculate references on a threadpool thread. However a certain portion of the language service (called the Language Analysis engine) is written in native code, so we had to do some cross-boundary and cross-thread manupulation. Our developers Ian (from C# compiler) and HeeJae (from C# IDE) worked very very hard to investigate the dumps that you folks were sending in and finally they've found the bug. The good news is that as more and more of Visual Studio gets rewritten in managed code, we hope to see less of such bad bugs in the future.

    So thanks to you for clicking that "Send Error Report" button – it really helped us to fix the top 1 reported C# crash!

    Cannot open C# source file: Error message "The operation could not be completed. Invalid pointer." or "Object reference not set to an instance of an object"

    This one is due to the Tools Options Fonts and Colors using a raster font instead of a TrueType font:

    http://blogs.msdn.com/visualstudio/archive/2009/10/27/VS-2010-Beta2_3A00_--Workaround-for-Raster-Font-Settings-Issue.aspx

    The fix is easy: switch to a TrueType font such as Consolas or Courier New.

    The editor team has fixed this one already.

    The application cannot start (VS black screen)

    Weston writes about this one in detail: http://blogs.msdn.com/visualstudio/archive/2009/10/29/how-to-fix-the-application-cannot-start-error.aspx 

    This is due to us being unable to read certain profile settings.

    The workaround is basically to run devenv /resetuserdata from the Visual Studio command prompt, but I encourage you to follow the link above for more information (e.g. how to save your settings beforehand).

    This is already fixed as well (now even if the profile contains the errors we will start successfully and deal with the errors).

    TextOptions does not appear in the IntelliSense in XAML designer

    The WPF team has completely rewritten the WPF text rendering to get rid of the font blurryness issue. The old style is still the default, to enable the new mode you need this simple attribute in your XAML: TextOptions.TextFormattingMode="Display". The problem is – TextOptions won't show up in IntelliSense!

    The workaround is to ignore IntelliSense and just build your project – things should just work.

    This has been fixed as well.

    All menus except the File menu disappear

    It happens extremely rarely, but we saw it three times already – the menus are just gone!

    image

    This one is very very hard to reproduce and we're still investigating this right now – for some unknown reason something is messing up the Style or the ControlTemplate for the menus. If you happen to run into this inside a virtual machine, you can really help us investigate the issue by pausing the machine in the state where VS is running and menus are gone.

    Feel free to open a bug on http://connect.microsoft.com/visualstudio/feedback or let me know and we'll send you instructions on how to upload the VM image.

    Unable to cast COM object of type 'System.__ComObject' to interface type 'Microsoft.VisualStudio.Editor.Implementation.IVsGlobalUndoCapableUndoManager'.

    ---------------------------

    Microsoft Visual Studio

    ---------------------------

    Unable to cast COM object of type 'System.__ComObject' to interface type 'Microsoft.VisualStudio.Editor.Implementation.IVsGlobalUndoCapableUndoManager'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{305E8709-55B7-4732-B872-1C073AB58047}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

    ---------------------------

    OK

    ---------------------------

     

    Right now we can't reproduce it so we're looking for any help – call stack, minidump with heap, ActivityLog.xml etc. You can read more about the ActivityLog here:

    http://msdn.microsoft.com/en-us/library/ms241272.aspx

    We'd appreciate any help!

    Expression.Compile generates incorrect code for (int?) conversion

    using System;
    using System.Linq.Expressions;
    
    class Program
    {
        static void Main()
        {
            Expression<Func<ValueType, int?>> expr = x => (int?)x;
            Func<ValueType, int?> converter1 = x => (int?)x;
            Func<ValueType, int?> converter2 = expr.Compile();
    
            int? a1 = converter1(null); // (int?) null
            int? a2 = converter2(null); // NRE
        }
    }

    Expected: both the direct delegate and the one generated with Expression Trees should work identically. Actual: the expression tree one throws a NullReferenceException.

    Thanks to controlflow for reporting this! It's a good bug, but unfortunately it will require a risky compiler change that we don't want to take so late in the product cycle. We've postponed the bug for a later release.

    Delegate.Combine doesn't support variance

    using System;
    
    class A { }
    class B : A { }
    
    class Program
    {
        static void Main()
        {
            Action<B> b = _ => { };
            Action<A> a = _ => { };
            b += a;
        }
    }

     

    This program compiles fine but causes an exception at runtime. The CLR team decided to postpone this to a future version.

    Completion List doesn't show up for certain lambda parameters in multiple overload scenarios

    using System;
    
    using System.Linq;
    using System.Threading.Tasks;
    
    class Program
    {
        static void Main(string[] args)
        {
            var query = Enumerable.Range(0, 100);
            Parallel.ForEach(query, (i, p) =>
            {
                Console.WriteLine(i);
                p.
            });
        }
    }

     

    In this code, IntelliSense doesn't show after p. Another great bug from controlflow. We've fixed this one (it had to deal with picking the right overload of ForEach given an incomplete lambda statement).

    Debugger data tips are leaking GDI handles

    Hovering the mouse cursor over variables during debugging and expanding the nodes in the tips will leak GDI handles. After the Visual Studio process will run out of GDI handles (and each process can only allocate 10,000 handles), it will crash. Usually this happens after 10-15 minutes of intensive debugging with datatips, depending on circumstances. You can watch the GDI handles of the devenv.exe process in the Task Manager (if you select GDI in View –> Select Columns).

    This is a stress bug that has been fixed by the debugger team recently.

    Tooltips on toolbar buttons are not displaying keyboard shortcuts

    As part of the WPF rewrite, we had postponed this work until very late, and only recently have fixed it (post Beta 2). Now all the keyboard shortcuts show up when you hover your mouse over a toolbar button. You will not be able to turn them off though :)

    Printing formatted source code with color is not supported

    This is actually not a bug, it's by design. We had to cut this low-impact feature from 2010 because of tight resources constraints as we've reimplemented the editor from scratch. This feature will hopefully come back in a later release of Visual Studio, maybe as an add-in.

    More High DPI and other accessibility issues

    I just keep finding more and more High DPI issues, hoping that if I find and report them now, you guys won't have to.

    Combobox missing right edge:

    image

    The shell team decided not to fix this because of tight schedule and resources.

    Snippets background poorly visible on High Contrast Black

    image

    The editor team has decided not to fix this because the colors are configurable.

    Silverlight Out-of-Browser settings dialog clips some controls under 120 DPI

    We're looking into fixing this right now.

  • Kirill Osenkov

    Copy Code in HTML format with Visual Studio 2010

    • 23 Comments

    Today Jason has announced the Visual Studio 2010 Productivity Power Tools – a set of VS 2010 extensions that we released to complement and enhance the built-in 2010 features. You can either install the Pro Power Tools from here or just go to the Tools –> Extension Manager and type "Pro Power Tools" in the search box:

    image

    For the Pro Power Tools, I wrote a feature to copy formatted source code to clipboard in HTML format. The traditional VS editor only copies the plain text and RTF formats to clipboard, and there are numerous tools available to convert RTF to HTML. With the Pro Power Tools installed, pressing Ctrl+C or otherwise copying the code editor selection to clipboard, it will place the formatted and colorized HTML fragment on clipboard, alongsize the plain text and RTF format.

    Then you can paste the code anywhere HTML is supported, such as Windows Live Writer:

    image

    Ctrl+Shift+V (Paste Special), Alt+K (Keep Formatting) and Enter to insert the colorized code to Live Writer.

    In a future version of the power tools I will introduce customization – you will be able to fully control what HTML gets generated:

    1. Prepend any HTML to the code fragment
    2. Append any HTML to the code fragment
    3. Prepend any HTML before every line of code
    4. Append any HTML after every line of code
    5. Include line numbers and the format string for them
    6. Replace the space with &nbsp;
    7. Replace the carriage return line feed with <br />
    8. Emit <span style="color: blue">void</span> vs. <span class="keyword">void</span>

    Also, the current version has a bug: Cut (Ctrl+X) doesn't place formatted HTML to clipboard, only Copy does. I forgot to hook up the Edit.Cut command and never got around to fixing it. I'll fix it for the next release though.

    Hope you like it, and as always, your feedback is appreciated!

    P.S. Here's the sample code formatted using the extension:

            private static string IntersperseLineBreaks(string text)
            {
                text = text.Replace("\n\r", "\n \r");
                return text;
            }
    You can View Source on this page, look for IntersperseLineBreaks and view the HTML that I generate. In a future release you will be able to customize the output of the tool, but for now this is what it defaults to.
  • Kirill Osenkov

    Too much type information, or welcome back System.Object and boxing

    • 22 Comments

    We all know that generics are good - they promote code reuse, static type checking by the compiler, increase runtime performance, allow more flexible OOP designs, lay the foundation for LINQ, help the IDE to provide more helpful IntelliSense and have tons and tons of other vital advantages. "var" is another good feature, which (unlike "object"), also helps to preserve full static type information.

    However I hit a rare case recently where I had too much static type information about my code, so I had to use System.Object (and boxing) to get the desired effect. I had a method that used reflection to set a property on a type, similar to this:

    static void SetProperty(object f)
    {
        Type type = f.GetType();
        PropertyInfo property = type.GetProperty("Bar");
        property.SetValue(f, 1, new object[0]);
    }

    I also had a struct like this:

    struct Foo
    {
        public int Bar { get; set; }
    }

    Now, I tried to set the Bar property on an instance of the struct:

    static void Main(string[] args)
    {
        var f = new Foo();
        SetProperty(f);
        Foo foo = (Foo)f;
        Console.WriteLine(foo.Bar);
    }

    It didn't work! It printed out 0! I was puzzled. And then I realized what is happening. Since Foo is a struct, and f (thanks to var!) is also statically known to be a struct, the compiler passes a copy of the struct by value to the SetProperty method. This copy is modified, but the original f is not.

    One simple change and it started working fine:

    static void Main(string[] args)
    {
        object f = new Foo();
        SetProperty(f);
        Foo foo = (Foo)f;
        Console.WriteLine(foo.Bar);
    }

    I changed var to object, the struct was boxed into an object on the heap, the reference to this same object was passed to the SetProperty method, method set the property on the boxed instance, and (Foo) unboxed the same modified instance - the code now prints out 1 and everything is OK again.

    "var" provided too much type information to the compiler - it avoided boxing, and knew that the variable is a struct, so I lost the modified value. After casting to object, we hid the extra information from the compiler and got the uniform behavior for both value types and reference types.

    In my original code where I encountered this peculiar behavior (a custom deserializer that reads XML and uses reflection to set properties on objects), I was too focused on working with all types so I forgot that those can be value types as well. Since I had everything strongly typed with generics, type inference, vars and other modern goodness, the kind hardworking compiler preserved all the information for me and avoided boxing where I was expecting to get reference type behavior. Thankfully, unit-tests revealed the error 10 minutes after it was introduced (I definitely need to post about the usefulness of unit-tests and TDD in the future), so it was a quick fix to box a type into object before filling its properties.

    It was an amusing experience.

  • Kirill Osenkov

    Remote Desktop: /span across multiple monitors

    • 21 Comments

    I spent some time searching the web about Remote Desktop, fullscreen and multiple monitors, so I decided to write down my findings to avoid having to search for them again.

    /span for multiple monitors

    If you pass /span to mstsc.exe, the target session’s desktop will become a huge rectangle that equals to the summary area of your physical monitors. This way the remote desktop window will fill all of your screens. The downside of this approach is that both screens are part of one desktop on the remote machine, so if you maximize a window there, it will span all of your monitors. Also, a dialog that is centered, will show up right on the border between your monitors. There is software on the web to workaround that but I’m fine with keeping my windows restored and sizing them myself. Also Tile Vertically works just fine in this case.

    Saving the /span option in the .rdp file

    There is a hidden option that isn’t mentioned in the description of the .rdp format:

    span monitors:i:1

    Just add it at the bottom of the file.

    Saving the /f (fullscreen) option in the .rdp file

    screen mode id:i:2

    (By default it’s screen mode id:i:1, which is windowed).

    Sources

  • Kirill Osenkov

    What’s faster: string.Equals or string.Compare?

    • 20 Comments

    I just realized I was so busy lately that I haven’t blogged for a while!

    Here’s a quiz that left me clueless for some time (courtesy of our C# MVP Ahmed Ilyas):

    using System;
    using System.Diagnostics;

    public class Examples
    {
        public static void Main()
        {
            string stringToTest = "Hello";

            Stopwatch equalsTimer = new Stopwatch();
            equalsTimer.Start();
            stringToTest.Equals("hello", StringComparison.OrdinalIgnoreCase);
            equalsTimer.Stop();
            Console.WriteLine("Equals Timer: {0}", equalsTimer.Elapsed);

            Stopwatch compareTimer = new Stopwatch();
            compareTimer.Start();
            String.Compare(stringToTest, "hello", StringComparison.OrdinalIgnoreCase);
            compareTimer.Stop();
            Console.WriteLine("Compare Timer: {0}", compareTimer.Elapsed);
        }
    }

    On my machine, this prints out:

    Equals Timer: 00:00:00.0009247
    Compare Timer: 00:00:00.0000012

    We looked at the source code of string.Equals and string.Compare and it was essentially the same (modulo very minor details which shouldn’t cause issues).

    So what’s wrong? Why would the first call be 770 times slower than the second one? Jitting? No. Cache hit/miss? No.

    After a while, we figured it out [UPDATE: So I thought!]. The first method is a virtual instance method, so a callvirt is emitted by the compiler:

    callvirt instance bool [mscorlib]System.String::Equals(string, valuetype [mscorlib]System.StringComparison)

    While the second method is a static one, so the call instruction is used instead:

    call int32 [mscorlib]System.String::Compare(string, string, valuetype [mscorlib]System.StringComparison)

    In this case, the method body was insignificant compared to the costs of doing virtual dispatch vs. a direct call. If you’d measure this in a loop of 1000000, the results will average out. So will they average out if you compare long strings, when the method body execution time dwarfs the call costs.

    UPDATE: As always, Kirill jumps to conclusions too fast. Ahmed pointed out that if you swap the order of the calls, then the results are way different again! So it’s not the callvirt cost. Still puzzled, maybe it IS the JITter compiling the BCL code for the two method bodies.

    Interesting...

  • Kirill Osenkov

    Updated C# all-in-one file

    • 20 Comments

    Thanks to everyone who came up with suggestions on my Did I miss any C# syntax construct? post.

    The updated file is below.

    #error Error message
    #warning Warning message
    #pragma warning disable 414, 3021
    #pragma warning restore 3021
    #line 6
    #line 2 "test.cs"
    #line default
    #line hidden
    #define foo
    #if foo
    #else
    #endif
    #undef foo

    extern alias Foo;

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Text;
    using M = System.Math;

    #if DEBUG || TRACE
    using System.Diagnostics;
    #elif SILVERLIGHT
    using System.Diagnostics;
    #else
    using System.Diagnostics;
    #endif

    #region Region

    #region more
    using ConsoleApplication2.Test;
    #endregion
    using X = int1;
    using X = ABC.X<int>;

    #endregion

    [assembly: System.Copyright(@"(C) 2009")]
    [module: System.Copyright("\n\t\u0123(C) 2009" + "\u0123")]

    class TopLevelType : IDisposable
    {
        void IDisposable.Dispose() { }
    }

    namespace My
    {
        using A.B;

        interface CoContra<out T, in K> { }
        delegate void CoContra2<out T, in K> () where T : struct;

        public unsafe partial class A : C, I
        {
            [method: Obsolete]
            public A([param: Obsolete] int foo) :
                base(1)
            {
            L:
                {
                    int i = sizeof(int);
                    ++i;
                }

    #if DEBUG
          Console.WriteLine(export.iefSupplied.command);
    #endif
                const int? local = int.MaxValue;
                const Guid? local0 = new Guid(r.ToString());

                var привет = local;
                var мир = local;
                var local3 = 0, local4 = 1;
                local3 = local4 = 1;
                var local5 = null as Action ?? null;
                var local6 = local5 is Action;

                var u = 1u;
                var U = 1U;
                long hex = 0xBADC0DE, Hex = 0XDEADBEEF, l = -1L, L = 1L, l2 = 2l;
                ulong ul = 1ul, Ul = 1Ul, uL = 1uL, UL = 1UL,
                    lu = 1lu, Lu = 1Lu, lU = 1lU, LU = 1LU;

                bool @bool;
                byte @byte;
                char @char = 'c', \u0066 = '\u0066', hexchar = '\x0130', hexchar2 = (char)0xBAD;
                string \U00000065 = "\U00000065";
                decimal @decimal = 1.44M;
                dynamic @dynamic;
                double @double = M.PI;
                float @float = 1.2f;
                int @int = local ?? -1;
                long @long;
                object @object;
                sbyte @sbyte;
                short @short;
                string @string = @"""/*";
                uint @uint;
                ulong @ulong;
                ushort @ushort;
               
                dynamic dynamic = local5;
                var add = 0;
                var ascending = 0;
                var descending = 0;
                var from = 0;
                var get = 0;
                var global = 0;
                var group = 0;
                var into = 0;
                var join = 0;
                var let = 0;
                var orderby = 0;
                var partial = 0;
                var remove = 0;
                var select = 0;
                var set = 0;
                var value = 0;
                var var = 0;
                var where = 0;
                var yield = 0;

                if (i > 0)
                {
                    return;
                }
                else if (i == 0)
                {
                    throw new Exception();
                }
                var o1 = new MyObject();
                var o2 = new MyObject(var);
                var o3 = new MyObject { A = i };
                var o4 = new MyObject(@dynamic)
                {
                    A = 0,
                    B = 0,
                    C = 0
                };
                var o5 = new { A = 0 };
                var dictionaryInitializer = new Dictionary<int, string>
                {
                    {1, ""},
                    {2, "a"}
                };
                float[] a = new float[]
                {
                    0f,
                    1.1f
                };
                int[] arrayTypeInference = new[] { 0, 1, };
                switch (i)
                {
                    case 1:
                        {
                            goto case 2;
                        }
                    case 2:
                        {
                            goto default;
                            break;
                        }
                    default:
                        {
                            return;
                        }
                }
                while (i < 10)
                {
                    ++i;
                }
                do
                {
                    ++i;
                }
                while (i < 10);
                for (int j = 0; j < 100; ++j)
                {
                    Console.WriteLine(j);
                }
                foreach (var i in Items())
                {
                    if (i == 7)
                        return;
                    else
                        continue;
                }
                checked
                {
                    checked(++i);
                }
                unchecked
                {
                    unchecked(++i);
                }
                lock (sync)
                    process();
                using (var v = BeginScope())
                using (A a = new A())
                using (BeginScope())
                    return;
                yield return this.items[3];
                yield break;
                fixed (int* p = stackalloc int[100])
                {
                    *intref = 1;
                }
                unsafe
                {
                    int* p = null;
                }
                try
                {
                    throw null;
                }
                catch (System.AccessViolationException av)
                {
                    throw av;
                }
                catch (Exception)
                {
                    throw;
                }
                finally
                {
                    try { } catch { }
                }
                var anonymous =
                {
                    A = 1,
                    B = 2,
                    C = 3,
                };
                var query = from c in customers
                            let d = c
                            where d != null
                            join c1 in customers on c1.GetHashCode() equals c.GetHashCode()
                            join c1 in customers on c1.GetHashCode() equals c.GetHashCode() into e
                            group c by c.Country
                                into g
                                orderby g.Count() ascending
                                orderby g.Key descending
                                select new { Country = g.Key, CustCount = g.Count() };
            }
            ~A()
            {
            }
            private readonly int f1;
            [Obsolete]
            [NonExisting]
            [Foo::NonExisting(var, 5)]
            [CLSCompliant(false)]
            [Obsolete, System.NonSerialized, NonSerialized, CLSCompliant(true || false & true)]
            private volatile int f2;
            [return: Obsolete]
            [method: Obsolete]
            public void Handler(object value)
            {
            }
            public int m<T>(T t)
              where T : class, new()
            {
                base.m(t);
                return 1;
            }
            public string P
            {
                get
                {
                    return "A";
                }
                set;
            }
            public abstract string P
            {
                get;
            }
            public abstract int this[int index]
            {
                protected internal get;
                internal protected set;
            }
            [method: Obsolete]
            [field: Obsolete]
            [event: Obsolete]
            public readonly event Event E;
            [event: Test]
            public event Action E1
            {
                [Obsolete]
                add { value = value; }
                [Obsolete]
                [return: Obsolete]
                remove { }
            }
            public static A operator +(A first, A second)
            {
                Delegate handler = new Delegate(Handler);
                return first.Add(second);
            }
            [method: Obsolete]
            [return: Obsolete]
            public static bool operator true(A a)
            {
                return true;
            }
            public static bool operator false(A a)
            {
                return false;
            }
            class C
            {
            }
        }
        public struct S : I
        {
            public S()
            {
            }
            private int f1;
            [Obsolete]
            private volatile int f2;
            public abstract int m<T>(T t)
              where T : struct
            {
                return 1;
            }
            public string P
            {
                get
                {
                    int value = 0;
                    return "A";
                }
                set;
            }
            public abstract string P
            {
                get;
            }
            public abstract int this[int index]
            {
                get;
                internal protected set;
            }
            public event Event E;
            public static A operator +(A first, A second)
            {
                return first.Add(second);
            }
            fixed int field[10];
            class C
            {
            }
        }
        public interface I
        {
            void A(int value);
            string Value
            {
                get;
                set;
            }
        }
        [type: Flags]
        public enum E
        {
            A,
            B = A,
            C = 2 + A,

    #if DEBUG
        D,
    #endif

        }
        public delegate void Delegate(object P);
        namespace Test
        {
            using System;
            using System.Collections;
            public class Список
            {
                public static IEnumerable Power(int number, int exponent)
                {
                    Список Список = new Список();
                    Список.Main();
                    int counter = 0;
                    int אתר = 0;
                    while (++counter++ < --exponent--)
                    {
                        result = result * number + +number+++++number;
                        yield return result;
                    }
                }
                static void Main()
                {
                    foreach (int i in Power(2, 8))
                    {
                        Console.Write("{0} ", i);
                    }
                }
            }
        }
    }

    namespace ConsoleApplication1
    {
        namespace RecursiveGenericBaseType
        {
            class A<T> : B<A<T>, A<T>>
            {
                protected virtual A<T> M() { }
                protected abstract B<A<T>, A<T>> N() { }
                static B<A<T>, A<T>> O() { }
            }

            sealed class B<T1, T2> : A<B<T1, T2>>
            {
                protected override A<T> M() { }
                protected sealed override B<A<T>, A<T>> N() { }
                new static A<T> O() { }
            }
        }

        namespace Boo
        {
            public class Bar<T> where T : IComparable
            {
                public T f;
                public class Foo<U> : IEnumerable<T>
                {
                    public void Method<K, V>(K k, T t, U u)
                        where K : IList<V>, IList<T>, IList<U>
                        where V : IList<K>
                    {
                        A<int> a;
                    }
                }
            }
        }

        class Test
        {
            void Bar3()
            {
                var x = new Boo.Bar<int>.Foo<object>();
                x.Method<string, string>(" ", 5, new object());

                var q = from i in new int[] { 1, 2, 3, 4 }
                        where i > 5
                        select i;
            }

            public static implicit operator Test(string s)
            {
                return new ConsoleApplication1.Test();
            }
            public static explicit operator Test(string s)
            {
                return new Test();
            }

            public int foo = 5;
            void Bar2()
            {
                foo = 6;
                this.Foo = 5.GetType(); Test t = "sss";
            }

            public event EventHandler MyEvent = delegate { };

            void Blah()
            {
                int i = 5;
                int? j = 6;

                Expression<Func<int>> e = () => i;
                Expression<Func<bool, Action>> e2 = b => () => { return; };
                Func<bool, bool> f = delegate (bool a)
                {
                    return !a;
                };
                Action a = Blah;
            }

            public Type Foo
            {
                [Obsolete("Name", error = false)]
                get
                {
                    return typeof(IEnumerable<>);
                }
                set
                {
                    var t = typeof(System.Int32);
                    t.ToString();
                    t = value;
                }
            }

            public void Constants()
            {
                int i = 1 + 2 + 3 + 5;
                global::System.String s = "a" + (System.String)"a" + "a" + "a" + "a" + "A";
            }

            public void ConstructedType()
            {
                List<int> i = null;
                int c = i.Count;
            }
        }
    }

    namespace Comments.XmlComments.UndocumentedKeywords
    {
        /// <summary>
        /// Whatever
        /// </summary>
        /// <!-- c -->
        /// <![CDATA[c]]> //
        /// <c></c> /* */
        /// <code></code>
        /// <example></example>
        /// <exception cref="bla"></exception>
        /// <include file='' path='[@name=""]'/>
        /// <permission cref=" "></permission>
        /// <remarks></remarks>
        /// <see cref=""/>
        /// <seealso cref=" "/>
        /// <value></value>
        /// <typeparam name="T"></typeparam>
        class /*///*/C<T>
        {
            void M<U>(T t, U u)
            {
                // comment
                /* *** / */
                /* //
                 */
                /*s*///comment
                // /***/
                /*s*/int /*s*/intValue = 0;
                intValue = intValue /*s*/+ 1;
                string strValue = /*s*/"hello";
                /*s*/MyClass c = new MyClass();
                string verbatimStr = /*s*/@"\\\\";
            }
        }

        //General Test F. Type a very long class name, verify colorization happens correctly only upto the correct size (118324)
        class TestClassXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/*Scen8*/{ }

        class TestClassXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX22/*Scen9*/{ }

        class yield
        {
            void Foo<U>(__arglist)
            {
                C<U> c = null;
                c.M<int>(5, default(U));
                TypedReference tr = __makeref(c);
                Type t = __reftype(tr);
                int j = __refvalue(tr, int);
                Params(a: t, b: t);
            }
            void Params(ref dynamic a, out dynamic b, params dynamic[] c) {}
            void Params(out dynamic a = 2, ref dynamic c = default(dynamic), params dynamic[][] c) {}

            public override string ToString() { return base.ToString(); }

            public partial void OnError();

            public partial void method()
            {
                int?[] a = new int?[5];/*[] bug*/ // YES []
                int[] var = { 1, 2, 3, 4, 5 };/*,;*/
                int i = a[i];/*[]*/
                Foo<T> f = new Foo<int>();/*<> ()*/
                f.method();/*().*/
                i = i + i - i * i / i % i & i | i ^ i;/*+ - * / % & | ^*/
                bool b = true & false | true ^ false;/*& | ^*/
                b = !b;/*!*/
                i = ~i;/*~i*/
                b = i < i && i > i;/*< && >*/
                int? ii = 5;/*? bug*/ // NO ?
                int f = true ? 1 : 0;/*? :*/   // YES :
                i++;/*++*/
                i--;/*--*/
                b = true && false || true;/*&& ||*/
                i << 5;/*<<*/
                i >> 5;/*>>*/
                b = i == i && i != i && i <= i && i >= i;/*= == && != <= >=*/
                i += 5.0;/*+=*/
                i -= i;/*-=*/
                i *= i;/**=*/
                i /= i;/*/=*/
                i %= i;/*%=*/
                i &= i;/*&=*/
                i |= i;/*|=*/
                i ^= i;/*^=*/
                i <<= i;/*<<=*/
                i >>= i;/*>>=*/
                object s = x => x + 1;/*=>*/
                Point point;
                unsafe
                {
                    Point* p = &point;/** &*/
                    p->x = 10;/*->*/
                }
                IO::BinaryReader br = null;
            }

            struct Point { public int X; public int Y; }
        }
  • Kirill Osenkov

    Coding productivity: macros, shortcuts and snippets

    • 19 Comments

    Visual Studio macros are a fantastic productivity booster, which is often under-estimated. It's so easy to record a macro for your repetitive action and then just play it back. Even better, map a macro to a keyboard shortcut. I'll share a couple of examples.

    InsertCurlies

    If you open up Visual Studio and type in this code:

    Void1

    How many keystrokes did you need? I've got 10 (including holding the Shift key once). It's because I have this macro mapped to Shift+Enter:

    Sub InsertCurlies()
        DTE.ActiveDocument.Selection.NewLine()
        DTE.ActiveDocument.Selection.Text = "{"
        DTE.ActiveDocument.Selection.NewLine()
        DTE.ActiveDocument.Selection.Text = "}"
        DTE.ActiveDocument.Selection.LineUp()
        DTE.ActiveDocument.Selection.NewLine()
    End Sub

    So I just typed in void Foo() and hit Shift+Enter to insert a pair of curlies and place the cursor inside. Remarkably, I've noticed that with this macro I now almost never have to hit the curly brace keys on my keyboard. Readers from Germany will especially appreciate this macro, because on German keyboard layouts you have to press Right-Alt and the curly key, which really takes some time to get used to.

    This macro is also useful to convert an auto-property to a usual property: you select the semicolon and hit Shift+Enter:

    ConvertAutopropToProp1

    Try it out!

    ConvertFieldToAutoProp

    Suppose you have a field which you'd like to convert to an auto-implemented property:

    ConvertFieldToAutoprop1

    And when you click the menu item, you get:

    ConvertFieldToAutoprop2

    How did I do it? First, here's the macro:

        Sub ConvertFieldToAutoprop()
            DTE.ActiveDocument.Selection.StartOfLine( _
                vsStartOfLineOptions.vsStartOfLineOptionsFirstText)
            DTE.ActiveDocument.Selection.EndOfLine(True)
    
            Dim fieldtext As String = DTE.ActiveDocument.Selection.Text
    
            If fieldtext.StartsWith("protected") _
                Or fieldtext.StartsWith("internal") _
                Or fieldtext.StartsWith("private") Then
                fieldtext = fieldtext.Replace("protected internal", "public")
                fieldtext = fieldtext.Replace("protected", "public")
                fieldtext = fieldtext.Replace("internal", "public")
                fieldtext = fieldtext.Replace("private", "public")
            ElseIf Not fieldtext.StartsWith("public") Then
                fieldtext = "public " + fieldtext
            End If
    
            fieldtext = fieldtext.Replace(";", " { get; set; }")
    
            DTE.ActiveDocument.Selection.Text = fieldtext
        End Sub
    

    And then just add the macro command to the refactor context menu or any other place. This may seem like no big deal, but I had to convert fields to auto-properties recently in 50+ files. I really learned to appreciate this macro.

    gs code snippet

    This is a very little but useful snippet: gs expands to { get; set; }

    <?xml version="1.0" encoding="utf-8" ?>
    <CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
        <CodeSnippet Format="1.0.0">
            <Header>
                <Title>gs</Title>
                <Shortcut>gs</Shortcut>
                <Description>Code snippet for { get; set; }</Description>
                <Author>Microsoft Corporation</Author>
                <SnippetTypes>
                    <SnippetType>Expansion</SnippetType>
                </SnippetTypes>
            </Header>
            <Snippet>
                <Code Language="csharp"><![CDATA[{ get; set; }$end$]]>
                </Code>
            </Snippet>
        </CodeSnippet>
    </CodeSnippets>

    Although I usually use the prop snippet to create auto-implemented properties, but gs is useful in some cases as well.

    I hope this has inspired you to do some personal usability research experiments and define everyday actions that you can optimize using macros, snippets and shortcuts. I would love to hear about your personal tips and tricks as well.

    kick it on DotNetKicks.com

  • Kirill Osenkov

    Stress testing Visual Studio 2010

    • 18 Comments

    In the past several months Visual Studio and I have been really busy stress testing each other. This post is a general overview on what we've been up to and what kind of testing we're doing. I've learned a lot about stress testing and I have to say it's actually a lot of fun, so I guess it's worth sharing. I'll try to make this a series of several posts, diving into more technical details in the upcoming posts.

    Background

    During Beta 1 and Beta 2 it became painfully obvious that the new VS had an obesity problem: it was slow, consumed a lot of memory and the worst thing, with enough modules loaded it stopped fitting into the 2GB address space on 32-bit machines. There were several reasons for this, which Rico Mariani, Brian Harry and others have extensively blogged about. In a nutshell, with a lot of new functionality a lot more modules were loaded into memory. Besides, we now had to fully load the CLR and WPF at application startup. Moreover, there were all kinds of memory leaks all over the place.

    Making performance a top priority

    Of course this wasn't good, so our management made the right decision to make performance our top priority. Jason really took it seriously and we dedicated a lot of people to work fulltime to make Visual Studio fast and lean. As part of this effort I became a member of a virtual team called "Perf SWAT". This team is responsible for essentially three things: performance, memory consumption and design-time stress.

    Performance is clear: we need to be fast. Memory consumption is clear too: when we load, we need to take as little memory as possible, and avoid things such as double-loaded modules, loading both NGEN and IL versions of an assembly, and so on.

    Design-time stress on the VSL team

    As for design-time stress, the goal is once we're loaded into memory, jitted, warmed up and all the caches are filled, we should not continue to grow in consumption. This means find and eliminate all memory and resource leaks. Run-time stress means finding leaks in the CLR and BCL, design-time stress means finding leaks in the VS and tooling. I am responsible for design-time stress testing for the VSL team (managed languages). I need to make sure that there are no significant leaks in 4 areas:

    1. C# IDE and editor integration (C# code editor, navigation, refactorings and other core C# areas)
    2. VB IDE and editor integration
    3. F# IDE
    4. Hostable Editor (Workflow Designer in VS 2010 is essentially hosting a full-blown language service to show IntelliSense in the expression editor on the workflow diagram)

    Progress

    The good news is that we've made tremendous progress since Beta 2 and have brought the product into a much better state: it is much faster, more responsive, takes up much less memory and we also hope to have eliminated all major known memory leaks. A common complaint was that VS was growing in memory during usage and you had to restart it after a certain time. Right now we hope that you can mostly keep Visual Studio open for days (even weeks) without having to restart it.

    8 hour stress tests

    The official sign-off criteria is that the end user needs to be able to keep VS open for an entire work week without any noticeable performance degradation (this means 5 days times 8 hours a day). We've calculated that in average continuous human usage of 40 hours is equivalent to running our tests for 8 hours (tests are doing things faster than a human).

    We have identified and implemented a series of 22 tests for all the 4 language teams mentioned above. Each test covers one continuous kind of activity, e.g. CSharpStressEditing, CSharpStressNavigation, CSharpStressIntelliSense, CSharpStressDebugging, CSharpStressUI, VBStressEditing, VBStressProjectSystem, FSharpStressEditing, and so on.

    Each test runs for 8 hours on a machine in the lab and VS memory usage details are automatically logged. We've also developed tools to automatically analyze the stress logs and produce Excel spreadsheets and charts for analysis and reporting.

    Several months ago a typical test would start at about 300 MB ProcessWorkingSet and crash after several hours with OOM (Out-Of-Memory exception). None of the tests would even be able to run for 8 hours. After finding and fixing a lot (a lot!) of bugs, we were able to get it running for 8 hours – VS memory usage grew from about 300-400 MB of WorkingSet to over 1 GB over the period of 8 hours (that was anywhere from 200-500 stress iterations).

    Right now a typical test starts at about 150-200 MB and finishes 8 hours later at 200-300 MB. Also, instead of 500 iterations, it is able to do 3000-5000 iterations during 8 hours on the same hardware. Which means we made it considerably faster and also reduced the leaks in major feature areas to a minimum (right now a feature is considered not leaking if there is average increase of less then ~5KB per iteration).

    I'll try to continue blogging about our stress testing and dive more into the technical details: what we measure, how we measure, how we find bugs and how we'll know when we're eventually done.

  • Kirill Osenkov

    Visual Studio 2010 New Editor screenshot

    • 18 Comments

    I’m very happy with how the Visual Studio editor improved since Beta1:

    image

    This is all WPF and includes the WPF 4.0 text rendering changes (DWrite integration). Note the new Zoom combobox in the bottom-left (which is the visual counterpart of Ctrl+ScrollWheel). Also the cross to close the tab is now located ON the tab, and not on the rightmost edge of the document. It takes about a day to get used to, but after you get used to it, it’s really awesome.

    I believe that the editor team has done a phenomenal job making the editor better for all of us. Note that although the screenshot was made from a remote desktop to a virtual machine, it still looks much better than in Beta1. And believe me, it is way faster and more reliable now.

    I’m very excited for Beta2 and can’t wait to get the bits out for you to play with!

  • Kirill Osenkov

    How I started to really understand generics

    • 16 Comments

    First off, a little explanation for the post title: not that I didn't understand generics before. I'd had a pretty good understanding of how they work, how they are implemented in the CLR, what facilities are provided by the compiler, etc.

    It's just that recently I started seeing some patterns and analogies that I hadn't seen before or just didn't pay enough attention to. This is a little fuzzy feeling but I'll still try and describe these insights, hopefully the reader will understand what I mean. These insights have helped me to think more clearly and have a better understanding of how to use generics in a richer way.

    For a start, let's consider a method called Process that processes command line arguments and modifies the argument list by removing the arguments that it could process:

    public ArgumentList Process(ArgumentList source)
    {
    
    }

    This design is not very good because it mutates the source variable, and I read somewhere that a method should either be immutable and return something or mutate stuff and return void, but not both at the same time. I think it was in Martin Fowler's Refactoring, but I'm not sure.

    But that's not the thing I wanted to talk about today. This design has another serious flaw: it essentially truncates its return type to be ArgumentList, so by calling this method we basically "seal" the output type to be ArgumentList:

    CustomArgumentList customList = new CustomArgumentList();
    ArgumentList processed = Process(customList);

    Even if we originally had a CustomArgumentList, once we pass it into our method, it "truncates" the type and all we have left on the output is the basic ArgumentList. We lose some type information and cannot enjoy the benefits of static typing and polymorphism at its fullest.

    So what have generics to do with all this? Well, generics allow us to "unseal" the return type of our method and to preserve the full static type information available:

    public T Process<T>(T source)
        where T : ArgumentList
    {
    }

    This way we can call Process on our CustomArgumentList and receive a CustomArgumentList back:

    CustomArgumentList customList = new CustomArgumentList();
    CustomArgumentList processed = Process(customList);

    See, type information is not sealed anymore and can freely "flow" from the input type to the output type. Generics enabled us to use polymorphism and preserve full static typing where it wasn't possible before. It might be obvious for many of you, but it was a wow-effect discovery for me. Note how we used type inference to make a call to Process<T> look exactly like a call to Process.

    Another observation here is that when you're talking about covariance and contravariance of generics, you can divide type usages into two groups: "in" and "out". Thus, we can have return type covariance and input parameter contravariance. Let's notice how "out" type usages essentially truncate the type information and limit ("seal") it to one base type. Generics are there to "unseal" this limitation and to allow for derived types to be returned without losing type information.

    I hope this wasn't too fuzzy and handwavy. It's just these little discoveries make me very excited and I'd like to share the way I see these things.

    Let's consider another insight: what's the difference between:

    1. class MyType<T> : IEquatable<T> and
    2. class MyType<T> where T: IEquatable<T>

    Update: I'd like to explain in a little bit more detail, what's going on here. In the first line, we're declaring that the type MyType<T> implements the IEquatable<T> interface (complies with the IEquatable<T> contract). Simpler said, MyType<T> is IEquatable<T> (can be compared with objects of type T). The <T> part reads "of T", which means MyType has a method Equals that accepts a parameter of type T. Hence, the first line imposes the constraint on the type MyType<T> itself.

    Now the second line imposes the constraint on the type parameter, not on the type itself. Now the type parameter that you specify must be a type that has an Equals method that accepts a parameter of type T (objects of type T can be compared with other objects of type T). I would imagine second line could be useful more often than the first line.

    Also, another line is possible:

    class MyType<T> : IEquatable<MyType<T>>

    This line would mean that MyType can be compared with itself (and, independently of this fact, use some other type T).

    Thinking about this difference made another aspect of generics clearer for me: with generics, there are always at least two different types involved: the actual type and the generic type parameters.

    Armed with this wisdom, let's move to a third mental exercise (again, it might all be simple and obvious for some readers, in this case I apologize and am very honored to have such readers). Is the following thing valid?

    class MyGenericType<T> : T
    {
    }

    It turns out it's not valid - we cannot inherit from a generic type parameter (Update: in the original post I wrote that this would lead to multiple inheritance - that's not true). This illustrates my previous points - with generics, there are always at least two different types involved, and we shouldn't mix them arbitrarily.

    Finally, to at least partially save this post from being a complete theoretical disaster, I'd like to share some code I wrote recently. Suppose you're implementing the Command design pattern and have various concrete Commands: CutCommand, CopyCommand, CloseAllDocuments command etc. Now the requirement is to support a unified exception throwing and catching functionality - every command should throw a generic exception InvalidOperationException<T>, where T is the type of the command. You might find this weird (who needs generic exceptions?) but in my real project at work we have some very clever exception classification logic, which requires that each exception should have a different type. Basically, each exception should know what type threw it. Based on this strongly typed exception source information, we do some magic to greatly simplify logging and classify exceptions into buckets based on their root cause. Anyway, here's the source code:

    class Command
    {
        public virtual void Execute() { }
    }
    
    class InvalidOperationException<T> : InvalidOperationException
        where T : Command
    {
        public InvalidOperationException(string message) : base(message) { }
        // some specific information about
        // the command type T that threw this exception
    }
    
    static class CommandExtensions
    {
        public static void ThrowInvalidOperationException<TCommand>(
            this TCommand command, string message) 
            where TCommand : Command
        {
            throw new InvalidOperationException<TCommand>(message);
        }
    }
    
    class CopyCommand : Command
    {
        public override void Execute()
        {
            // after something went wrong:
            this.ThrowInvalidOperationException("Something went wrong");
        }
    }
    
    class CutCommand : Command
    {
        public override void Execute()
        {
            // after something went wrong:
            this.ThrowInvalidOperationException("Something else went wrong");
        }
    }

    Note how two seemingly equal calls to ThrowInvalidOperationException will, in fact, throw different exceptions. The call in CopyCommand will throw an InvalidOperationException<CopyCommand>:

    image

    while the same call from CutCommand will throw an InvalidOperationException<CutCommand>:

    image

    Here (attention!) we infer the type of the command from the type of the "this" reference. If you try calling it without the "this." part, the compiler will fail to resolve the call:

    image

    So this is a situation where extension methods and generic type inference play nicely together to enable what I think is a very interesting trick. We preserve type information all the way from where an exception is thrown, "remember" the type that threw the exception, and still have full type information available when we catch and process it. A nice example of how generics help type information "flow" from one part of your code to other. This is also in line with my first example where we see how type information "flows" from input to output parameter of a method.

    Note: for those of you who spent some time with Prolog, don't you have a déjà vu of how Prolog allows values to "flow" between predicates? In Prolog every parameter to a predicate (method) can be "in" or "out" - input or output. Prolog infers which parameter is which depending on its usage elsewhere and inside the predicate body. I don't know if this analogy is valid at all, but I feel that C# compiler in a certain way does its type inference in a similar manner.

  • Kirill Osenkov

    A curious subtlety about how CLR does interface dispatch on array types

    • 15 Comments

    This post is about some internal CLR magic that usually makes accessing .NET arrays through an interface up to 100 times faster (if you're an optimist; or accessing arrays up to 100 times slower in the worst case, if you're a pessimist). I'm usually very curious about how this universe works under the hood - and finding out about the internals of the CLR for me is like discovering laws of physics :) So if you ever find yourself measuring the timing of array access through generic interfaces in performance critical code, this post is probably worth taking a look at.

    Anyway, here's the story. A customer (Robert Kieboom from CityGIS) has reported an intermittent performance decrease when accessing arrays through the IList<T> interface. Specifically, for some weird reason, same codepath started executing 100 times slower after a call to some seemingly unrelated code. Huge thanks to Robert for providing this precise and exact repro (I hope he doesn't mind if I share it):

    class Program
    {
        public static int AddValues(IList<int> list)
        {
            int add = 0;
            /*foreach ( int value in list )
              add += value;*/
            for (int i = 0; i < list.Count; i++)
                add += list[i];
            return add;
        }
    
        static void TestAddArray(int[] items)
        {
            Stopwatch timer = Stopwatch.StartNew();
            AddValues(items);
            timer.Stop();
            Console.WriteLine("Array: {0} ms.", timer.ElapsedMilliseconds);
        }
    
        static void TestAddIList(int[] items)
        {
            IList<int> cl = new List<int>(items);
    
            Stopwatch timer = Stopwatch.StartNew();
            AddValues(cl);
            timer.Stop();
    
            Console.WriteLine("IList: {0} ms.", timer.ElapsedMilliseconds);
        }
    
        static void Main(string[] args)
        {
            int[] items = new int[1000000];
            for (int i = 0; i < items.Length; i++)
                items[i] = i - (items.Length / 2);
    
            TestAddArray(items); // fast
            TestAddArray(items); // fast
    
            TestAddIList(items); // something weird happens??!
    
            TestAddArray(items); // slow
            TestAddArray(items); // slow
        }
    }

    Here's what this program does. First we call TestAddArray a couple of times that uses an array disguised as an IList<int> - both calls are very fast, each about 108ms on my machine.

    Then we call TestAddIList that uses a List<int> disguised as an IList<int> - this call is even faster, 21 ms.

    Now - watch this - both subsequent calls to TestAddArray take 3638ms and 3677ms respectively - about 33 times slower!

    If you remove the call to TestAddIList(items), all four calls will be equally fast. What's going on? The same codepath becomes slower after some random call? We were puzzled. After Eric couldn't find any explanation for this from the C# compiler standpoint (we were producing correct IL), it was clear that the issue is deeper than IL and has to do with the execution engine itself. So I routed the bug to the CLR team - and pretty soon we had a reply from them.

    It turns out, CLR has some optimizations on how they do virtual dispatch on a generic interface, if the runtime type is an array. As I'm afraid to talk nonsense outside of my area of expertise, I'll just quote the bug description from the CLR folks:

    The problem is rooted in the fact that IList<T>::get_Item is an interface invocation on an array type (in the example an int[]).  Because arrays are very common, and interface dispatch through interfaces like IList<T> is uncommon, the runtime saves significant space by having special logic for dispatching through generic interfaces like these. 

    Our interface dispatch logic has an important optimization where FOR EACH CALL SITE, it checks one particular target explicitly, and if that fails, does slower hash table lookup, and if that lookup fails, fall back to an  expensive lookup.  Thus for calls sites that tend to go to one destination it is very fast, and call sites that go to many targets, you get good, but not as great performance.

    As it turns out, there is a problem in the special logic for dispatch logic for arrays (but not for ordinary interfaces) that cause the hash table lookup to fail.    What this means is either interface dispatch FOR ARRAY TYPES  is very fast (if the explict check works), or very slow (when it does not). 

    In the fast case, the interface calls to 'get_Item and get_count' (used in the [] operator) call with at 'this' pointer of int[] first, which means this is the value that is used for the 'fast check'.   The second time we call it with List<int>, not int[]. However since there is no bug associated with normal (not array) dispatch, everything works well.

    However when the benchmarks are reversed, List<int> is the first 'this' that dispatches through 'get_Item' and 'get_Count' call sites so they get the benefit of the fast check. When the first benchmark is run, it now dispatches using an int[] as the 'this' pointer, and because of the bug, the hash table lookup always fails and so only the very slow lookup mechanism is used.

    Workarounds:

    1) In performance critical code, ensure that if arrays are passes as IList<T> (or super Interfaces), that T[] is always called first.  There is a good chance that this approach is impractical, but if there are only a few such critical paths then it is possibly useful. 

    2) Always use List<T> where you would have used T[]. By the way, if you can avoid using Collection<T> that is probably a good thing, as it is a wrapper that in most cases does not add much value.

    3) In any performance critical paths, special case the array case with code like

                 method(IList<T> aIList)

                 {

                        T[] asArray = aList as T[]

                        if (asArray != null)

                        {

                                  // logic on arrays

                        }

                        else

                        {

                                  // logic on aList

                        }

    Option 3 has the advantage that it is SIGNIFICANTLY faster than interface dispatch will ever be because the array check is done only once (and then lots of operations are done), rather than effectively being done on every interface invocation. I would not recommend any work-around that does not have some positive effect on your code base.  I could believe that options 2 and 3 MAY be a superior solution in the long term anyway, so I would suggest investigating them.

    This explains why calling arrays through generic interfaces might under certain conditions become considerably slower (or, alternatively, why these calls are in many cases considerably faster than the general case). In any case, virtual dispatch is slower than calling array members directly, so if you have a chance, just work with arrays directly or use generic collections like List<T>.

    Regarding the future fate of this particular CLR optimization failing in some cases, we are considering whether we shall fix it for the next release of the .NET framework. However, as always: no promises here folks! If you do hit this problem (which is pretty unlikely), just use the workarounds for now - thankfully they are easy and reliable.

    I hope this was insightful and many folks have found this interesting - I'd like to give credit to everyone who reported, reproduced and investigated this issue (including, among others, Robert Kieboom, Arie Leeuwesteijn, Erik Meijer, Eric Lippert, Vance Morrison and Jan Kotas) - and I hope they don't mind me sharing this with the rest of the .NET world.

  • Kirill Osenkov

    Reflections on coding style

    • 15 Comments

    I've been monitoring my coding style for quite a while and I noticed that I often prefer chaining method calls to normal control flow. Now I think it might not always be such a good idea.

    To give you an example, today I had a task of reflecting over constants in a class and stuffing them into a dictionary. Here's a sample to demonstrate my original approach. In this sample I replaced the actual domain model with a fake colors domain and the task is to implement two methods: FillColors and OutputColors.

    using System;
    using System.Collections.Generic;
    
    static class Program
    {
        public const string Red = "#FF0000";
        public const string Green = "#00FF00";
        public const string Blue = "#0000FF";
    
        static void Main(string[] args)
        {
            var dictionary = new Dictionary<string, string>();
            FillColors(dictionary.Add);
            OutputColors(dictionary);
        }
    
        static void FillColors(Action<string, string> add)
        {
            var fields = typeof(Program).GetFields();
            fields.ForEach(f => add(f.Name, f.GetRawConstantValue().ToString()));
        }
    
        static void OutputColors(Dictionary<string, string> dictionary)
        {
            dictionary.ForEach(p => Console.WriteLine(p.Key + " = " + p.Value));
        }
    
        static void ForEach<T>(this IEnumerable<T> list, Action<T> action)
        {
            foreach (var item in list)
            {
                action(item);
            }
        }
    }

    First, several interesting comments about the code.

    • constants are public because otherwise Type.GetFields won't find them. And for the life of me I couldn't figure out how the overload of GetFields works that accepts BindingFlags. I didn't want to spend more than 2 minutes on that so I just made the constants public.
    • there are no more access modifiers, because members are private by default and top-level types are internal by default if the access modifier is missing. Jon Skeet wrote in his C# in Depth book that he prefers omitting the modifier if it corresponds with the default visibility and I really like this style. Makes the programs shorter. Short programs are especially useful for us testers, where we need to find a minimal repro for bugs that we report.
    • FillColors accepts a delegate "add" which I like calling "the collector". It could have accepted the entire dictionary, but I only use the add functionality so to minimize coupling I only require what I actually consume. An alternative here would be to implement an iterator using yield return, but this would require returning a list of pairs of values, and Tuples were not in our TFS branch yet at the moment of writing :) Another reason for "the collector" pattern is that yield return doesn't compose well - flattening lists like Comega does is still not in C# as of 4.0. Contrary to that, passing a delegate (Continuation-Passing Style) composes nicely and is fully supported starting from C# 1.0.
    • OutputColors doesn't accept IEnumerable<KeyValuePair<string, string>> because I was to lazy to spell that out and it is not relevant to the current discussion :)
    • Also OutputColors doesn't accept Action<string> and hardcodes Console.WriteLine because of the KISS/YAGNI principle.
    • I don't know why KISS/YAGNI didn't apply to the FillColors method. It just didn't.

    But I digress. Let's go back to the actual topic of me writing one long line:

    fields.ForEach(f => add(f.Name, f.GetRawConstantValue().ToString()));

    instead of:

    foreach (var f in fields)
    {
        add(f.Name, f.GetRawConstantValue().ToString());
    }

    Here are several observations that favor foreach against ForEach:

    ForEach is not in the library

    As of .NET 3.5 SP1, ForEach is not in the library so I had to implement it myself. For .NET 4.0 I've logged a suggestion with Mads to add it to the BCL, but I'm not sure if we're adding it for 4.0. A lot of people seem to add it to their libraries so I think it'll be useful to have regardless of the coding style it suggests. I'm sure it is useful at least sometimes.

    ForEach hides state mutation

    Eric Lippert told me that he's not a great fan of ForEach because it conceals state mutation - it takes an eager (non-lazy) control flow statement that mutates state and hides it behind a functionally-looking call.

    You can't put a breakpoint inside ForEach "body"

    If you use foreach, you can put a breakpoint on the add call, whereas you can't put a breakpoint on the add call in the first case. This is not a language problem, but rather a tooling issue, but still I don't see tools (yes, debugger, I'm looking at you!) becoming comfortable enough in this scenario anytime soon.

    Stack is polluted

    In the first case (ForEach), two additional frames are on the stack which looks kinda ugly during debugging:

    image

    vs. the original:

    image

    This may not have a good impact on the debugging story.

    Performance is worse

    Although I know that micro-managing performance is a bad thing to do, we still create an anonymous method (metadata bloat) and have two additional calls on the stack (I know that JIT will probably optimize them, but who knows). So the danger is that in critical codepaths (bottlenecks) the performance will degrade compared to using control flow (which the JIT will compile into a couple of nice fast JMP instructions).

    Readability suffers

    Readability is probably worse because ForEach is not as familiar as foreach. Also, the code lines tend to grow long with the first approach and I like my lines of code less than 80 characters.

    ForEach is NOT functional style

    I'd like to stress that I'm still a huge fan of functional style, immutability, composability, first-class functions, etc. The ForEach style described in this blog-post is NOT functional style, although it definitely looks like it.

    1. It is NOT immutable
    2. It is NOT idempotent
    3. It does not chain as Kevin mentions
    4. It is NOT lazy and doesn't have deferred execution like many LINQ operators which are truly functional

    We had a hallway conversation with Chris Smith from F# team about this coding style topic today, and even he (the functional programming guy and a huge F# fan) admitted that sometimes C# should better use C# native constructs instead of borrowing from other (albeit awesome) languages like F#.

    Summary

    So I guess I'm going back to more using good old control flow statements again as they deserve it. They have been here for 30 years for a good reason and I don't think they're going away anytime soon.

  • Kirill Osenkov

    Kirill’s Whitespace Guidelines for C#

    • 15 Comments

    I don’t remember seeing any explicit guidelines on whitespace formatting for C# programs, however it seems that experienced C# developers all format their C# code files in a very similar fashion, as if there are some implicit but widely-accepted rules. In this post, I’ll try to formalize my own rules that I use intuitively when I format C# code. I’ll add more to it as I discover new stuff and correct things based on your feedback.

    No two consecutive empty lines

    Bad:

       1:  static void Main(string[] args)
       2:  {
       3:      Main(null);
       4:  }
       5:   
       6:   
       7:  static void Foo()
       8:  {
       9:      Foo();
      10:  }

    No empty line before a closing curly

    Bad:

       1:          Main(null);
       2:   
       3:      }

    No empty line after an opening curly

    Bad:

       1:  class Program
       2:  {
       3:      
       4:      static void Main(string[] args)

    One empty line between same level type declarations

       1:  namespace Animals
       2:  {
       3:      class Animal
       4:      {
       5:      }
       6:   
       7:      class Giraffe : Animal
       8:      {
       9:      }
      10:  }

    One empty line between members of a type

       1:  class Animal
       2:  {
       3:      public Animal()
       4:      {
       5:      }
       6:   
       7:      public void Eat(object food)
       8:      {
       9:      }
      10:   
      11:      public string Name { get; set; }
      12:  }

    Whereas it’s OK to group single-line members:

       1:  class Customer
       2:  {
       3:      public string Name { get; set; }
       4:      public int Age { get; set; }
       5:      public string EMail { get; set; }
       6:   
       7:      public void Notify(string message)
       8:      {
       9:      }
      10:  }

    However every multi-line member must be surrounded by an empty line unless it’s the first or the last member, in which case there shouldn’t be a line between the member and the curly brace.

    One empty line after #region and before #endregion

    Usually #region should be treated as if it were the first construct from it’s content (in this example, a type member):

       1:  class Customer
       2:  {
       3:      #region Public properties
       4:   
       5:      public string Name { get; set; }
       6:      public int Age { get; set; }
       7:      public string EMail { get; set; }
       8:   
       9:      #endregion
      10:   
      11:      public void Notify(string message)
      12:      {
      13:      }
      14:  }

    Within a #region, it’s contents should be separated from the #region/#endregion by a single empty line. Usually #regions contain type members or whole types, less often parts of a method body.

    I think these are the major rules that come into mind for now. If I remember more, I’ll update this post. Also, definitely feel free to contribute any corrections/additions and I’ll update the post too. Thanks!

  • Kirill Osenkov

    First videos of the structured editor prototype

    • 15 Comments

    Disclaimer: the structured editor work described in my posts is unrelated to my work at Microsoft. Everything shown is my personal research done as part of my MSc thesis during 2004-2007. Also, it’s not ready for real use and does not cover all the features of even C# 1.0. It’s a concept prototype and work in progress.

    Introduction

    As part of my research back in school I was building an experimental structured editor for C#. Now I’ve decided to publish the sources and binaries on CodePlex:

    http://structurededitor.codeplex.com

    A detailed discussion of structured editors deserves a separate post, which is coming soon. For now, to give a better idea of how the editor works, I’ve recorded six short videos showing the different features below. If your blog reader doesn’t support iframes, I recommend you view this post in the browser.

    What is a structured editor?

    Programs are represented as text by most code editors. Structured editors, on the contrary, directly display the syntax tree of a program on screen and allow the user to manipulate the tree directly (think MVC: program parse tree is a model, the editor displays a view of it):

    This way the visual layout better illustrates the structure of the program and allows for atomic operations on the language constructs. A structured editor lets developers avoid syntax errors and concentrate on the meaning of the program instead of formatting.

    1. Introduction

    2. Editing

    You will notice that there is no intellisense and coloring at the expression level – I did build a SharpDevelop add-in that hosts the structured editor control inside the SharpDevelop project system (DOM), but these videos were recorded on a stand-alone version of the structured editor control hosted inside an empty windows form. Also the support at the expression level is rudimentary, because so far I’ve concentrated the most at declaration level (namespaces, types, members) and statement level (except for single-line statements such as assignments).

     

    3. Drag & Drop Support

    4. No Parser Means Less Syntax

    5. Properties

    6. Modifiers

    Background

    Structured editing is a topic surrounded with scepticism and controversy for the past 20-30 years. Some argue that directly editing the AST on screen is inflexible and inconvenient, because the constraints of always having a correct program restrict the programmer way too much. Others expect structured editors to be more helpful than text editors because the user operates atomically and precisely on the language constructs, concentrating on the semantics and not on syntax.

    In summer 2004, my professor Peter Bachmann initiated a student research project - we started building a structured editor for C#. I took part because I was deeply persuaded that good structured editors can actually be built, and it was challenging to go and find out for myself. After the original project was over, I took over the basic prototype and evolved it further to the state it is today.

    As one of numerous confirmations for my thoughts, in 2004, Wesner Moise wrote:

    ...I see a revolution brewing within the next three years in the way source code is written.

    Text editors are going to go away (for source code, that is)! Don't get me wrong, source code will still be in text files. However, future code editors will parse the code directly from the text file and will be display in a concise, graphical and nicely presented view with each element in the view representing a parse tree node. ...

    I remember how I agreed with this! After three years, in 2007, the prototype implementation was ready - it became the result of my master's thesis. I still agree with what Wesner was envisioning in 2004 - with one exception. Now I believe that structured editors shouldn't (and can't) be a revolution - fully replacing text editors is a bad thing to do. Instead, structured editors should complement text editors to provide yet another view on the same source tree (internal representation, or AST).

    My conclusions about structured editors

    1. Text-based editors aren’t going away anytime soon.
    2. Structured editors can only succeed by evolution, not revolution – hybrid approach and ability to toggle between text and structure is the way to go.
    3. The main difficulty with structured editors is getting the usability right.
    4. The right approach is solving all the numerous little problems one by one – find a solution for every situation where a text editor is better (from my experience, for any advantage of a text editor, a good structured solution can be found).
    5. You need a graphical framework with auto-layout such as WPF to build a structured editor.
    6. Don’t try to build a universal editor editor that can edit itself – this approach is too complex. Take a specific language and build a hardcoded editor for this language first. Only after you’ve built 2-3 successful editors, it makes sense to generalize and build a universal editor or an editor generator.
    7. Compilers shouldn’t be a black box, but expose the data structures as a public API surface.
    8. Syntax trees should be observable so that the editor can databind to them.
    9. Traditional expression editor should be hostable inside a structured editor for single-line statements and expressions.

    As a result of my work, I'm convinced that structured editors actually are, in some situations, more convenient than text editors and providing the programmer with two views on the code to choose from would be a benefit. Just like Visual Studio Class Designer - those who want to use it, well, just use it, and the rest continues to happily use the text editor. All these views should co-exist to provide the programmer with a richer palette of tools to chooce from.

    Hence, my first important conclusion. A program's internal representation (the AST) should be observable to allow the MVC architecture - many views on the same internal code model. With MVC, all views will be automatically kept in sync with the model. This is where for example something like WPF data-binding would come in handy.

    As for the structured editor itself - it is still a work in progress and I still hope to create a decent complement for text editors. It has to be usable and there are still a lot problems to solve before I can say: "Here, this editor is at least as good as the text editor". But I managed to solve so many challenging problems already, that I'm optimistic about the future.

    Current implementation

    The current implementation edits a substantial subset of C# 1.0 - namespaces, types, members (except events), and almost all statements. If you're interested, you can read more at http://www.guilabs.net and www.osenkov.com/diplom - those are two sites I built to tell the world about my efforts. I also accumulate my links about structured editing here: http://delicious.com/KirillOsenkov/StructuredEditors

    More languages

    It turned out that it makes sense to build structured editors not only for C#, but for other languages as well - XML, HTML, Epigram, Nemerle, etc. That is why, at the very beginning, the whole project was split in two parts - the editor framework and the C# editor built on top of it.

    Links

    1. http://structurededitor.codeplex.com
    2. http://guilabs.net
    3. http://www.osenkov.com/diplom
    4. http://delicious.com/KirillOsenkov/StructuredEditors

    If you want to know more, or if you want to share your opinion on this, please let me know. I welcome any feedback! Thanks!

    kick it on DotNetKicks.com Shout it
  • Kirill Osenkov

    Visual Studio 2010 Beta 2 Known Issues

    • 14 Comments

    [This is Part 1. Read Part 2 here]

    Now that we’ve shipped Beta2 and the world is busy downloading the fresh new bits, I’m very excited to know what do you guys think? Will you like it? Will there be major issues that we missed? Time will show :)

    By definition, this Beta 2 release is not final, and there are still bugs lurking around out there. We are very busy fixing those bugs for RTM, but for now, there are some that we haven’t had time to fix before Beta2.

    This post lists some of the known issues that are in VS 2010 Beta 2. It’s not in my powers to maintain a comprehensive list here, I’ll just mention the ones which I was personally involved with in my day-to-day work. Apologies that I have found them too late, but I guess better late then never...

    Updates – new!

    Posted the Part 2 of the issues (updated 11/12/2009)

    http://blogs.msdn.com/kirillosenkov/archive/2009/11/12/visual-studio-2010-beta-2-known-issues-part-2.aspx

    All further updates will happen there or will wait until Part 3.

    The official Beta2 known issues list (updated 10/26/2009)

    http://go.microsoft.com/fwlink/?LinkID=166199

    Updating the .sln file from Beta1 to Beta2 (updated 10/26/2009)

    Need to upgrade .sln file from Beta2 in order to be able to double-click it. See Jon’s post here for more details:

    http://msmvps.com/blogs/jon_skeet/archive/2009/10/26/migrating-from-visual-studio-2010-beta-1-to-beta-2-solution-file-change-required.aspx

    Setup dialog UI layout wrong on High DPI

    image

    Embarrassing! Unfortunately, not everyone on the Visual Studio team is rigorous about non-default testing, such as High DPI, Accessibility, etc. We will hopefully fix this one before RTM. Also recent data shows that non-96 DPI is a very common setting, a lot of people actually use 120 DPI and others. I personally use 120 DPI, that’s how I find these bugs.

    SmartTag high DPI issues

    image

    With high DPI, the SmartTag menu is missing horizontal menu separator bars. Also the right vertical edge of the SmartTag button disappears. These bugs are a recent regression from WPF introducing the UseLayoutRounding API. The WPF team is looking into fixing these issues before the release.

    QuickInfo tooltip trimmed at high DPI

    image

    This is another regression from the new DWrite technology. The last word in the tooltip is missing! This one is fixed already.

    Thin line on top of the active document tab

    image

    Again, another high DPI issue. You can only notice this one if you look closely. We’ve fixed this already as well.

    Outlining Expand/Collapse glyphs are shifted several pixels up

    image

    Fixed already. A lot of people complained about this internally.

    Zoom combobox in the bottom-left corner of the editor isn’t aligned with the horizontal scrollbar

    image

    This is fixed.

    Don’t tear off the Call Hierarchy tool window!

    When you try to undock the C# Call Hierarchy toolwindow and drag it away (for example, to another monitor), VS will crash. This one is too embarrassing, because I was the one who is responsible for testing Call Hierarchy. To my defense, I was on vacation when this regressed and when I came back and found this, it was too late to fix. Shell UI team changed something about the WPF toolwindow implementation and we had some layout logic that didn’t expect double.Infinity as an argument, so we crashed. This one’s already fixed in recent builds.

    Vertical separator bar in the Call Hierarchy tool window doesn’t resize the details pane

    This also only reproes under 120 DPI and above. You can’t resize the two panes below by dragging the vertical bar:

    image

    And again, this is one that I should have caught and missed. When I caught this, it was too late to fix for Beta2. The WPF team is looking at this one right now.

    Error message connecting to a TFS server via HTTPS

    Well, guess what, the TFS client team has done it again! TFS HTTPS story was broken in Beta1, and it still has a bug in Beta2. However the good news is that there is a really easy workaround this time.

    When adding a new TFS HTTPS webserver (e.g. a Codeplex server at http://codeplex.com), after entering your credentials you will see this:

    image

    Don’t panic! Just enter your credentials again and things will work just fine. If you used the Tip (http://blogs.msdn.com/kirillosenkov/archive/2009/09/27/tip-don-t-enter-your-codeplex-credentials-every-time.aspx), then you will be unaffected by this and things will hopefully run smoothly.

    Ctrl+Alt+DOWN ARROW doesn’t bring up the active document list

    Ctrl+Alt+Down used to bring up the active document list, in Beta2 it doesn’t. This is fixed.

    Start Page: scroll wheel doesn’t work at the news feed

    Also the scrollbar thumb only moves in discrete steps. The Shell UI team decided not to fix this, because they don’t have time and resources for this. I actually was surprised to discover that the scrollbar didn’t work in 2008 either. Never noticed this until recently.

    VS Command prompt shortcut is not getting installed if you don’t install C++

    This one will be fixed as well.

    Hovering over ‘var’ during debugging doesn’t show the inferred type

    Jeffrey Richter told me about this minor annoyance. Although our language service correctly reports the inferred type when you hover the mouse cursor over ‘var’ in design time, it doesn’t work in debug mode. Since Jeff teaches a lot of courses in debugging and threading, this was bugging him ever since we shipped C# 3.0. Well, we finally fixed it for 2010 RTM. Thanks to Jeff for reporting this!

    Visual Studio doesn’t start maximized when first launched

    A while back I’ve logged a bug against the Shell team to “just start VS maximized for heaven’s sake”. They did the fix, but somehow it didn’t make it into the Beta2 branch. They’ll hopefully fix this for RTM.


    Well, these were the ones worth mentioning I guess. Apologies if you run into any of these or any other bugs for that matter. I will keep updating this post with more issues that I find or I think users should be aware of. Please keep in mind that this is an unofficial list.

    Please do let us know about any issues you find by submitting a connect bug. If the bug/suggestion/feedback is related to the C# language or IDE, also feel free to let me know directly or leave a comment on this blog. Since I work closely with the VS editor team, it’s worth watching their blog and giving them feedback: http://blogs.msdn.com/vseditor. Also, if you have any feedback about the new text rendering in WPF 4.0 and Visual Studio, the WPF Text team has a blog here: http://blogs.msdn.com/text.

  • Kirill Osenkov

    Did I miss any C# syntax construct?

    • 14 Comments

    Dear readers, I’m asking for your valuable input again.

    I went through some of our test files and combined a single “all-in-one” C# syntax file that I want to contain all C# 4.0 constructs. I’m specifically not looking for combinations (because there’s an infinite number, obviously), it’s enough to just mention each syntax construct once.

    So, is there anything I’m missing? (Sorry, it’s a huge junkyard!)

    #error Error message
    #warning Warning message
    #pragma warning disable 414, 3021
    #pragma warning restore 3021
    #line 6
    #define foo
    #if foo
    #else
    #endif
    #undef foo
    //#warning foo
    //#error foo

    extern alias Foo;

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Text;
    using M = System.Math;

    #if DEBUG || TRACE
    using System.Diagnostics;
    #elif SILVERLIGHT
    using System.Diagnostics;
    #else
    using System.Diagnostics;
    #endif

    #region Region

    #region more
    using ConsoleApplication2.Test;
    #endregion
    using X = int1;
    using X = ABC.X<int>;

    #endregion

    [assembly: System.Copyright(@"(C) 2009")]
    [module: System.Copyright("\n\t\u0123(C) 2009" + "\u0123")]

    namespace My
    {
        using A.B;

        interface CoContra<out T, in K> { }
        delegate void CoContra2<out T, in K> () where T : struct;

        public unsafe partial class A : C, I
        {
            [method: Obsolete]
            public A([param: Obsolete] int foo) :
                base(1)
            {
            L:
                {
                    int i = sizeof(int);
                    ++i;
                }

    #if DEBUG
          Console.WriteLine(export.iefSupplied.command);
    #endif
                const int? local = int.MaxValue;
                const Guid? local0 = new Guid(r.ToString());

                var привет = local;
                var мир = local;
                var local3 = 0, local4 = 1;
                var local5 = null as Action ?? null;
                var local6 = local5 is Action;

                var u = 1u;
                var U = 1U;
                long hex = 0xBADC0DE, Hex = 0XDEADBEEF, l = -1L, L = 1L;
                ulong ul = 1ul, Ul = 1Ul, uL = 1uL, UL = 1UL,
                    lu = 1lu, Lu = 1Lu, lU = 1lU, LU = 1LU;

                bool @bool;
                byte @byte;
                char @char = 'c', \u0066 = '\u0066', hexchar = '\x0130', hexchar2 = (char)0xBAD;
                decimal @decimal = 1.44M;
                dynamic @dynamic;
                double @double = M.PI;
                float @float;
                int @int = local ?? -1;
                long @long;
                object @object;
                sbyte @sbyte;
                short @short;
                string @string = @"""/*";
                uint @uint;
                ulong @ulong;
                ushort @ushort;
               
                dynamic dynamic = local5;
                var add = 0;
                var ascending = 0;
                var descending = 0;
                var from = 0;
                var get = 0;
                var global = 0;
                var group = 0;
                var into = 0;
                var join = 0;
                var let = 0;
                var orderby = 0;
                var partial = 0;
                var remove = 0;
                var select = 0;
                var set = 0;
                var value = 0;
                var var = 0;
                var where = 0;
                var yield = 0;

                if (i > 0)
                {
                    return;
                }
                else if (i = 0)
                {
                    throw new Exception();
                }
                var o1 = new MyObject();
                var o2 = new MyObject(var);
                var o3 = new MyObject { A = i };
                var o4 = new MyObject(@dynamic)
                {
                    A = 0,
                    B = 0,
                    C = 0
                };
                var o5 = new { A = 0 };
                int[] a = new int[]
          {
            0,
            1,
            2,
            3,
            4,
            5
          };
                switch (i)
                {
                    case 1:
                        {
                            goto case 2;
                        }
                    case 2:
                        {
                            goto default;
                            break;
                        }
                    default:
                        {
                            return;
                        }
                }
                while (i < 10)
                {
                    ++i;
                }
                do
                {
                    ++i;
                }
                while (i < 10);
                for (int j = 0; j < 100; ++j)
                {
                    Console.WriteLine(j);
                }
                foreach (var i in Items())
                {
                    if (i == 7)
                        return;
                    else
                        continue;
                }
                checked
                {
                    checked(++i);
                }
                unchecked
                {
                    unchecked(++i);
                }
                lock (sync)
                    process();
                using (var v = BeginScope())
                using (A a = new A())
                using (BeginScope())
                    return;
                yield return this.items[3];
                yield break;
                fixed (int* p = stackalloc int[100])
                {
                    *intref = 1;
                }
                unsafe
                {
                    int* p = null;
                }
                try
                {
                    throw null;
                }
                catch (System.AccessViolationException av)
                {
                    throw av;
                }
                catch (Exception)
                {
                    throw;
                }
                finally
                {
                }
                var anonymous =
                {
                    A = 1,
                    B = 2,
                    C = 3,
                };
                var query = from c in customers
                            let d = c
                            where d != null
                            join c1 in customers on c1.GetHashCode() equals c.GetHashCode()
                            join c1 in customers on c1.GetHashCode() equals c.GetHashCode() into e
                            group c by c.Country
                                into g
                                orderby g.Count() ascending
                                orderby g.Key descending
                                select new { Country = g.Key, CustCount = g.Count() };
            }
            ~A()
            {
            }
            private readonly int f1;
            [Obsolete]
            [NonExisting]
            [Foo::NonExisting(var, 5)]
            [CLSCompliant(false)]
            [Obsolete, System.NonSerialized, NonSerialized, CLSCompliant(true || false & true)]
            private volatile int f2;
            [return: Obsolete]
            [method: Obsolete]
            public void Handler(object value)
            {
            }
            public int m<T>(T t)
              where T : class, new()
            {
                base.m(t);
                return 1;
            }
            public string P
            {
                get
                {
                    return "A";
                }
                set;
            }
            public abstract string P
            {
                get;
            }
            public abstract int this[int index]
            {
                protected internal get;
                internal protected set;
            }
            [method: Obsolete]
            [field: Obsolete]
            [event: Obsolete]
            public readonly event Event E;
            [event: Test]
            public event Action E1
            {
                add { value = value; }
                remove { }
            }
            public static A operator +(A first, A second)
            {
                Delegate handler = new Delegate(Handler);
                return first.Add(second);
            }
            [method: Obsolete]
            [return: Obsolete]
            public static bool operator true(A a)
            {
                return true;
            }
            public static bool operator false(A a)
            {
                return false;
            }
            class C
            {
            }
        }
        public struct S : I
        {
            public S()
            {
            }
            private int f1;
            [Obsolete]
            private volatile int f2;
            public abstract int m<T>(T t)
              where T : struct
            {
                return 1;
            }
            public string P
            {
                get
                {
                    int value = 0;
                    return "A";
                }
                set;
            }
            public abstract string P
            {
                get;
            }
            public abstract int this[int index]
            {
                get;
                internal protected set;
            }
            public event Event E;
            public static A operator +(A first, A second)
            {
                return first.Add(second);
            }
            fixed int field[10];
            class C
            {
            }
        }
        public interface I
        {
            void A(int value);
            string Value
            {
                get;
                set;
            }
        }
        [type: Flags]
        public enum E
        {
            A,
            B = A,
            C = 2 + A,

    #if DEBUG
        D,
    #endif

        }
        public delegate void Delegate(object P);
        namespace Test
        {
            using System;
            using System.Collections;
            public class Список
            {
                public static IEnumerable Power(int number, int exponent)
                {
                    Список Список = new Список();
                    Список.Main();
                    int counter = 0;
                    int אתר = 0;
                    while (++counter++ < --exponent--)
                    {
                        result = result * number + +number+++++number;
                        yield return result;
                    }
                }
                static void Main()
                {
                    foreach (int i in Power(2, 8))
                    {
                        Console.Write("{0} ", i);
                    }
                }
            }
        }
    }

    namespace ConsoleApplication1
    {
        namespace RecursiveGenericBaseType
        {
            class A<T> : B<A<T>, A<T>>
            {
                protected virtual A<T> M() { }
                protected abstract B<A<T>, A<T>> N() { }
                static B<A<T>, A<T>> O() { }
            }

            class B<T1, T2> : A<B<T1, T2>>
            {
                protected override A<T> M() { }
                protected sealed override B<A<T>, A<T>> N() { }
                new static A<T> O() { }
            }
        }

        namespace Boo
        {
            public class Bar<T> where T : IComparable
            {
                public T f;
                public class Foo<U> : IEnumerable<T>
                {
                    public void Method<K, V>(K k, T t, U u)
                        where K : IList<V>, IList<T>, IList<U>
                        where V : IList<K>
                    {
                        A<int> a;
                    }
                }
            }
        }

        class Test
        {
            void Bar3()
            {
                var x = new Boo.Bar<int>.Foo<object>();
                x.Method<string, string>(" ", 5, new object());

                var q = from i in new int[] { 1, 2, 3, 4 }
                        where i > 5
                        select i;
            }

            public static implicit operator Test(string s)
            {
                return new ConsoleApplication1.Test();
            }
            public static explicit operator Test(string s)
            {
                return new Test();
            }

            public int foo = 5;
            void Bar2()
            {
                foo = 6;
                this.Foo = 5.GetType(); Test t = "sss";
            }

            void Blah()
            {
                int i = 5;
                int? j = 6;

                Expression<Func<int>> e = () => i;
            }

            public Type Foo
            {
                get
                {
                    return typeof(System.Int32);
                }
                set
                {
                    var t = typeof(System.Int32);
                    t.ToString();
                    t = value;
                }
            }

            public void Constants()
            {
                int i = 1 + 2 + 3 + 5;
                global::System.String s = "a" + (System.String)"a" + "a" + "a" + "a" + "A";
            }

            public void ConstructedType()
            {
                List<int> i = null;
                int c = i.Count;
            }
        }
    }

    namespace Comments.XmlComments.UndocumentedKeywords
    {
        /// <summary>
        /// Whatever
        /// </summary>
        /// <!-- c -->
        /// <![CDATA[c]]> //
        /// <c></c> /* */
        /// <code></code>
        /// <example></example>
        /// <exception cref="bla"></exception>
        /// <include file='' path='[@name=""]'/>
        /// <permission cref=" "></permission>
        /// <remarks></remarks>
        /// <see cref=""/>
        /// <seealso cref=" "/>
        /// <value></value>
        /// <typeparam name="T"></typeparam>
        class /*///*/C<T>
        {
            void M<U>(T t, U u)
            {
                // comment
                /* *** / */
                /* //
                 */
                /*s*///comment
                /*s*/int /*s*/intValue = 0;
                intValue = intValue /*s*/+ 1;
                string strValue = /*s*/"hello";
                /*s*/MyClass c = new MyClass();
                string verbatimStr = /*s*/@"\\\\";
            }
        }

        //General Test F. Type a very long class name, verify colorization happens correctly only upto the correct size (118324)
        class TestClassXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/*Scen8*/{ }

        class TestClassXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX22/*Scen9*/{ }

        class yield
        {
            void Foo<U>(__arglist)
            {
                C<U> c = null;
                c.M<int>(5, default(U));
                TypedReference tr = __makeref(c);
                Type t = __reftype(tr);
                int j = __refvalue(tr, int);
                Params(a: t, b: t);
            }
            void Params(ref dynamic a, out dynamic b, params dynamic[] c) {}
            void Params(out dynamic a = 2, ref dynamic c = default(dynamic), params dynamic[][] c) {}

            public override string ToString() { return base.ToString(); }

            public partial void method()
            {
                int?[] a = new int?[5];/*[] bug*/ // YES []
                int[] var = { 1, 2, 3, 4, 5 };/*,;*/
                int i = a[i];/*[]*/
                Foo<T> f = new Foo<int>();/*<> ()*/
                f.method();/*().*/
                i = i + i - i * i / i % i & i | i ^ i;/*+ - * / % & | ^*/
                bool b = true & false | true ^ false;/*& | ^*/
                b = !b;/*!*/
                i = ~i;/*~i*/
                b = i < i && i > i;/*< && >*/
                int? ii = 5;/*? bug*/ // NO ?
                int f = true ? 1 : 0;/*? :*/   // YES :
                i++;/*++*/
                i--;/*--*/
                b = true && false || true;/*&& ||*/
                i << 5;/*<<*/
                i >> 5;/*>>*/
                b = i == i && i != i && i <= i && i >= i;/*= == && != <= >=*/
                i += 5.0;/*+=*/
                i -= i;/*-=*/
                i *= i;/**=*/
                i /= i;/*/=*/
                i %= i;/*%=*/
                i &= i;/*&=*/
                i |= i;/*|=*/
                i ^= i;/*^=*/
                i <<= i;/*<<=*/
                i >>= i;/*>>=*/
                object s = x => x + 1;/*=>*/
                Point point;
                unsafe
                {
                    Point* p = &point;/** &*/
                    p->x = 10;/*->*/
                }
                IO::BinaryReader br = null;
            }

            struct Point { public int X; public int Y; }
        }
  • Kirill Osenkov

    A prototype WPF/Silverlight layout designer

    • 14 Comments

    I’ve been thinking recently about how would I write a WPF UI designer that would specifically highlight the new WPF layout paradigm, and not try to mimic the old WinForms paradigm. The old VB6/WinForms designer was built around absolute positioning. It allowed for rapid WYSIWYG prototyping of interfaces, and the Dock/Anchor functionality provided a relatively cheap and easy support for scalable UI. The new WPF designer in Visual Studio is although very powerful, but some people find it difficult to quickly draft a scalable UI that produces clean XAML.

    So I wrote a concept prototype of how I would like to design WPF UI:

    http://layout.osenkov.com

    It runs right in the browser and requires Silverlight 4 (because it needs to copy the output XAML to clipboard). It only focuses on the basics and doesn’t have a lot of features (it’s just a prototype), but I think it can nicely convey my ideas. Nothing of it is new, and both Blend and VS designers support complex layouts with panels and such, but I still decided to write a simple designer without a lot of complex details.

    Let me know what you think!

    image

  • Kirill Osenkov

    Algorithms in C#: shortest path around a polygon (polyline routing)

    • 14 Comments

    Suppose you have to build a road to connect two cities on different sides of a lake. How would you plan the road to make it as short as possible?

    To simplify the problem statement, a lake is sufficiently well modeled by a polygon, and the cities are just two points. The polygon does not have self-intersections and the endpoints are both outside the polygon. If you have Silverlight installed, you can use drag and drop on the points below to experiment:

    Get Microsoft Silverlight

    Solution description

    A shortest path between two points is a segment that connects them. It’s clear that our route consists of segments (if a part of the path was a curve other than a segment, we could straighten it and get better results). Moreover, those segments (which are part of the route) have their endpoints either on polygon vertices or the start or end point. Again, if this were not the case, we would be able to make the path shorter by routing via the nearest polygon vertex.

    Armed with this knowledge, let’s consider all possible segments that connect the start and end point and all polygon vertices that don’t intersect the polygon. Let’s then construct a graph out of these segments. Now we can use Dijkstra’s algorithm (or any other path finding algorithm such as A*) to find the shortest route in the graph between start and endpoints. Note how any shortest path algorithm can essentially boil down to a path finding in a graph, because a graph is a very good representation for a lot of situations.

    From the implementation perspective, I used my dynamic geometry library and Silverlight to create a simple demo project that lets you drag the start and end points as well as polygon vertices. You can also drag the polygon and the plane itself. I also added rounded corners to the resulting path and made it avoid polygon vertices to make it look better.

    Here is the source code for the sample. Here’s the main algorithm. It defines a data structure to describe a Graph that provides the ShortestPath method, which is the actual implementation of the Dijkstra’s algorithm. ConstructGraph takes care of adding all possible edges to the graph that do not intersect our polygon. SegmentIntersectsPolygon also determines what the name suggests.

    I hope to post more about polygon routing in the future and do let me know if you have any questions.

Page 1 of 7 (154 items) 12345»