July, 2009

  • Kirill Osenkov

    All C# Compiler Developer Team blogs

    • 2 Comments

    With Ian Halliday, a developer on the C# Compiler team who started to blog recently, all of the C# compiler devs are blogging! Here’s the list of their blogs sorted alphabetically:

  • Kirill Osenkov

    Instantiating types with no public constructors

    • 7 Comments

    It turns out, Activator.CreateInstance and Activator.CreateInstance<T> fail if there is no public parameterless constructor defined on a type we’re trying to instantiate. Even if the constructor is internal (basically, anything other than public), CreateInstance will fail. This one was a surprise actually, I would expect the reflection binder to work for internal constructors at least.

    Update: it turns out, there is an overload of Activator.CreateInstance(Type, bool) that does exactly what I want. Don’t use what I posted below :) Thanks to Andrey Shchekin for the tip!

    Nevertheless, a more powerful alternative to Activator.CreateInstance in this case is to find the non-public constructor and invoke it manually:

    using System;
    using System.Reflection;
    
    class Test
    {
        private Test() { }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            var flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
            var ctor = typeof(Test).GetConstructor(flags, null, new Type[0], null);
            var instance = ctor.Invoke(null);
    
            //var instance = Activator.CreateInstance<Test>(); // Exception: No parameterless constructor defined for this object.
            //var instance = Activator.CreateInstance(typeof(Test)); // Exception: No parameterless constructor defined for this object.
        }
    }

    Why do I need this? Well, there is a class in our codebase that everyone was instantiating all over the place. But this class should have inherently been a singleton. I changed the code all over the place to use a singleton instead of instantiating it and I wanted to prohibit people to instantiate this class in the future.

    We have a little Singleton helper that essentially looks like this:

    public class Singleton<T> where T : class
    {
        static T instance;
        public static T Instance
        { 
            get
            {
                if (instance == null)
                {
                    instance = Instantiate();
                }
                return instance;
            }
        }
    
        static T Instantiate()
        {
            return Activator.CreateInstance<T>();
        }
    }

    So I would just inherit the class that everyone was using from Singleton like this: CommonClass : Singleton<CommonClass> and make the constructor private so that people can’t instantiate it manually anymore. However this became a problem because the Singleton’s Instantiate() method failed for non-public constructors. Now that I’ve used the approach above, it works fine. Singleton can instantiate the class, but no one else can.

     

    P.S. Yes, I know about the right way to implement a singleton, I know about double-check locking and threading and that reflection is bad. But this solves the problem.

    P.P.S. Yes, I know about burning the base class and that mixing in a singleton via inheritance is generally a bad idea. It works for us and does it’s job.

    P.P.P.S. It occurred to me that if we had extension properties, one could have just made Instance an extension property on every type (that implements a certain “marker” interface). But there is no way currently to mix-in state into existing types (if you don’t look at WPF and their attached properties and dependency properties).

  • Kirill Osenkov

    Comparing doubles can produce unexpected results

    • 4 Comments

    Well, guess what, smart people learn from other people’s mistakes and Kirill learns from his own.

    This is actually a well-known caveat about doubles, but still a reminder about something to be aware of. A double value can be something else than you might think it is. For example, when you expect a double to be exactly 6, it could be 5.9999999999999991 and you will wonder, how on earth is it possible that 6 != 6:

    image

    The upper tooltip clearly shows that the second coordinate is 6, but comparing it with 6 fails. Whoa, the detailed view shows 5.9999999999999991.

    What’s up with that? Luckily, the .NET framework source is easily available, so a quick look at Point.ToString() reveals that they simply format the output to round away the last couple of precision digits. The X and Y on the contrary are displayed unformatted (or should I say formatted less aggressively).

    Under closer examination (and after half an hour of pulling my hair out) it looks like the system represented the calculation result as close to the decimal integer 6 it could, given the double precision in .NET encoded in binary. The failing code was comparing if (point.Y == 6) and the comparison failed against my expectations.

    The solutioin for this is to test for the fact, “is the value within epsilon of the ideal value of 6”, like this: if (Math.Abs(point.Y – 6) < 0.00000001) …

    I should have read more Eric back in school.

  • Kirill Osenkov

    Having Fun with the New Editor in VS 2010

    • 6 Comments

    I was figuring out how to test the new WPF editor through the new managed API and it suddenly occurred to me how easy it is to do things to the editor that just weren’t possible before. For example, I decided that I like my editor rotated:

    image

    Why? Because I can!

    public void RotateEditor(int degrees)
    {
        var textView = GetWpfTextView();
        textView.VisualElement.LayoutTransform = new RotateTransform(degrees);
    }

    What amazed me is that it continued to work just fine – I was expecting to find a ton of bugs this way, but things just continued to work seamlessly. And my test did this to the running instance of Visual Studio without even changing anything – I injected the above method in the VS main AppDomain and ran it on a currently opened document.

    Apart from meaningless entertainment “just for fun” you can do so much more useful stuff. For example, it’s super easy to insert images right into the editor:

    imageinsertion_01.png

    A friend of mine will soon be publishing a spell-checker add-in for XML comments that was very easy to write.

    You can find more samples and information about the new editor at the following locations:

    And finally, don’t forget to follow the New Editor on Twitter: http://twitter.com/vseditor

  • Kirill Osenkov

    Bling: a WPF Framework/Declarative Strongly-Typed DSL for Quick Expressive C# WPF Apps

    • 0 Comments

    Several weeks ago I met with Sean McDirmid from the Microsoft’s Research and Prototyping facility in Beijing to chat about IDE design and his recent projects. Sean is a well-known researcher with broad interests in languages, compilers, and, recently, WPF and graphics. He was demoing the (open-source) project he’s working on now: http://bling.codeplex.com. Here are some quotes from the project’s website:

    Bling is a C#-based library for easily programming images, animations, interactions, and visualizations on Microsoft's WPF/.NET. Features include:

      • Declarative constraints that maintain dynamic relationships in the UI without the need for complex event handling. For example, button.Width = 100 - slider.Value causes button to shrink as the slider thumb is moved to the right, or grow as it is moved to the left. Constraints have many benefits: they allow rich custom layouts to be expressed with very little code, they are easy animate, and they support UIs with lots of dynamic behavior. [Kirill: note that this is directly in C# with all the type checking! Think F# Units of Measure.]
      • Simplified animation with one line of code. For example, button.Left.Animate.Duration(500).To = label.Right will cause button to move to the right of label in 500 milliseconds. [Kirill: the magic of implicit conversions, operator overloading, extension methods and expression trees working together!]
      • Pixel shader effects without the need to write HLSL code or boilerplate code! For example, canvas.CustomEffect = (input, uv) => new ColorBl(new Point3DBl(1,1,1) - input[uv].ScRGB, input[uv].ScA); defines and installs a pixel shader on a canvas that inverts the canvas's colors. Pixel shading in Bling takes advantage of your graphics card to create rich, pixel-level effects. [Kirill: they do code-gen for this, I think by just spitting out C# code, not sure though.]
      • Support for multi-pass bitmap effects such as diffuse lighting.
      • An experimental UI physics engine for integrating physics into user interfaces! The physics supported by Bling is flexible, controllable, and easy to program.
      • Support for 2.5D lighting.
      • A rich library of geometry routines; e.g., finding where two lines intersect, the base of a triangle, the area of triangle, or a point on Bezier curve. These routines are compatible with all of Bling's features; e.g., they can be used in express constraints, pixel shaders, or physical constraints. Bling also provides a rich API for manipulating angles in both degrees and radians. [Kirill: Competition! Need to take a look at this and Live Geometry side-by-side, maybe we can benefit from each other’s work.]
      • And many smaller things; e.g., a frame-based background animation manager and slide presentation system. [Kirill: yeah, Sean did his demo in his own WPF app – no PowerPoint. Too bad he had to recompile it to fix a typo :)]
      • As a lightweight wrapper around WPF, Bling code is completely compatible with conventional WPF code written in C#, XAML, or other .NET languages [Kirill: and Silverlight].

    Essentially, they use a similar trick to what F# did with Units of Measure – they leverage the type system to represent strongly typed “units”, wrap types such as System.Double and Point using implicit conversions and use operator overloading, extension methods and more to create an expressive DSL for representing constraints, math formulas, etc. directly within the host language (C#). Bling also makes heavy use of expression trees to do intraspection and meta-programming – using C# expressions to capture the formula as opposed to capturing the value. After a quick glance at the source code, I also notice some DLR usage and code-generation techniques.

    What can we do with it? Well, Sean mentioned that this is great for rapid prototyping in C#, without ever using XAML. This framework is somewhat different from the WPF style, but it definitely looks interesting and champions what I think is a great collection of coding tricks cleverly combined into DSLs. Also, if you download and build the demo, it’s REALLY IMPRESSIVE. I don’t know about you, but I just love those eye-candy demos with bright colors, animations, gradients and other effects.

    Here are a couple screenshots for a start. For more, take a look at the Bling tutorial.

    image

    c0.jpg

    image

    a_distortB.jpg

    metaball.jpg

    Have fun!

  • Kirill Osenkov

    Silverlight 3 is out!

    • 0 Comments

    “Well, unless you’ve been living under a rock…” © CyrusN :)

    I’m very excited about Silverlight 3 which has TONS of new awesome features, from better graphics and text to out-of-browser support, style improvements and… drumroll… SaveFileDialog (finally) :)

    Links:

  • Kirill Osenkov

    http://silverlight.live.com

    • 0 Comments

    http://silverlight.live.com (Microsoft Silverlight Streaming) is a free service from Microsoft to host your Silverlight applications and videos. You can upload your .xap or .wmv files and reference them from any websites, blogs, etc. My favorite part is that you get 10 GB in free storage, with no ads, no strings attached. Also, they give you high scalability and availability – the media is hosted “in the cloud” that can handle a lot of traffic. Finally, you have a nice admin site where you can manage your account, videos and applications – you can upload new videos, applications, track usage (number of downloads or video views), etc.

    The MSDN Silverlight Streaming Samples page contains several nice Silverlight samples. I use http://silverlight.live.com to host http://livegeometry.com and my other applications and videos. Enjoy!

  • Kirill Osenkov

    Samples for the Undo Framework

    • 13 Comments

    I just added some samples for the Undo Framework. You can find the samples in the source code or download them from the project website.

    MinimalSample

    First is a simple Console App sample called MinimalSample. Here’s the full source code:

    using System;
    using GuiLabs.Undo;
    
    namespace MinimalSample
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Original color");
    
                SetConsoleColor(ConsoleColor.Green);
                Console.WriteLine("New color");
    
                actionManager.Undo();
                Console.WriteLine("Old color again");
    
                using (Transaction.Create(actionManager))
                {
                    SetConsoleColor(ConsoleColor.Red); // you never see Red
                    Console.WriteLine("Still didn't change to Red because of lazy evaluation");
                    SetConsoleColor(ConsoleColor.Blue);
                }
                Console.WriteLine("Changed two colors at once");
    
                actionManager.Undo();
                Console.WriteLine("Back to original");
    
                actionManager.Redo();
                Console.WriteLine("Blue again");
                Console.ReadKey();
            }
    
            static void SetConsoleColor(ConsoleColor color)
            {
                SetConsoleColorAction action = new SetConsoleColorAction(color);
                actionManager.RecordAction(action);
            }
    
            static ActionManager actionManager = new ActionManager();
        }
    
        class SetConsoleColorAction : AbstractAction
        {
            public SetConsoleColorAction(ConsoleColor newColor)
            {
                color = newColor;
            }
    
            ConsoleColor color;
            ConsoleColor oldColor;
    
            protected override void ExecuteCore()
            {
                oldColor = Console.ForegroundColor;
                Console.ForegroundColor = color;
            }
    
            protected override void UnExecuteCore()
            {
                Console.ForegroundColor = oldColor;
            }
        }
    }

    Here we define a new action called SetConsoleColorAction, and override two abstract methods: ExecuteCore() and UnExecuteCore(). In the ExecuteCore(), we change the color to the new color and backup the old color. In UnExecuteCore() we rollback to the backed up old color. We pass the action all the context information it needs (in our case, the desired new color). We rely on the action to backup the old color and store it internally.

    The philosophy is to only store the smallest diff as possible. Try to avoid copying the entire world if you can only save the minimal delta between states.

    Next, pay attention to the SetConsoleColor method. It wraps creating the action and calling RecordAction on it. It helps to create an API that abstracts away the action instantiation so that it is transparent for your callers. You don’t want your callers to create actions themselves every time, you just want them to call a simple intuitive API. Also, if for whatever reason you’d like to change or remove the Undo handling in the future, you’re free to do so without breaking the clients.

    Finally, the source code in Main shows how you can intersperse your API calls with calls to Undo and Redo. It also shows using a transaction to group a set of actions into a single “multi-action” (Composite design pattern). You can call your API within the using statement, but the actions’ execution is delayed until you commit the transaction (at the end of the using block). That’s why you don’t see the console color changing to red in the middle of the block. If you undo a transaction, it will undo all the little actions inside it in reverse order.

    WinFormsSample

    The second sample is called WinFormsSample. It shows a windows form that let’s you edit properties of a business object:

    image

    You can change the text of both name and age, and the values will be mapped to the business object. You can also “Set Both Properties” which illustrates transactions. Then you can click Undo and it will rollback the state of your object to the previous state. The UI will update accordingly.

    There is a trick in the code to avoid infinite recursion: on textbox text change, update the business object, fire an event, update the textboxes, update the business object again, etc... We use a boolean flag called “reentrancyGuard” that only enables the TextChanged events if the textbox modification was made by user, and not programmatically. If we updated the textboxes as a results of the business object change, no need to update the business object.

    Note: If this was WPF, I would just use two-way data binding, but I wanted to keep the sample as simple as possible and use only basic concepts.

    Action merging

    Another thing worth mentioning that this sample demonstrates is action merging. As you type in the name in the textbox ‘J’, ‘o’, ‘e’, you don’t want three separate actions to be recorded, so that you don’t have to click undo three times. To enable this, an action can determine if it wants to be merged with the next incoming action. If the next incoming action is similar in type to the last action recorded in the buffer, they merge into a single action that has the original state of the first action and the final state of the new action. This feature is very useful for recording continuous user input such as mouse dragging, typing and other events incoming at a high rate that you want to record as just one change.

    We update the visual state of the Undo and Redo buttons (enabled or disabled) to determine if the actionManager can Undo() or Redo() at the moment. We call the CanRedo() and CanUndo() APIs for this.

    Hopefully this has been helpful and do let me know if you have any questions.

Page 1 of 1 (8 items)