• Kirill Osenkov

    Windows Explorer Preview Pane for .vb files

    • 4 Comments

    I love using the Preview Pane in Windows Explorer to quickly preview file contents:

    image

    Usually, to enable this preview for a file extension I just open regedit, go to HKEY_CLASSES_ROOT –> .xxx (where xxx is the extension you’re interested in), and add a string key called PerceivedType with value of “text”: http://blog.wpfwonderland.com/2011/01/15/customize-windows-7-preview-pane-for-xaml-files/

    However for some reason it didn’t work for .vb files. After some web searching, one solution I found that worked for me is to add the preview handler GUID explicitly under a “shellex” key: http://www.howtogeek.com/howto/windows-vista/make-windows-vista-explorer-preview-pane-work-for-more-file-types/

    image

    Windows Registry Editor Version 5.00

    [HKEY_CLASSES_ROOT\.vb\shellex\{8895b1c6-b41f-4c1c-a562-0d564250836f}]
    @="{1531d583-8375-4d3f-b5fb-d23bbd169f22}"

  • Kirill Osenkov

    High accuracy DateTime.UtcNow

    • 5 Comments

    Update: in the original version of this post I’ve jumped to an incorrect conclusion that the timer resolution depends on the operating system. However thanks to a comment from James Manning who has corrected me, I realized that this is likely not related to the OS version (because we’re seeing high resolution DateTime on both Win7 and Windows Server 2008 R2).

    I’ve just discovered an interesting thing: apparently one of my machines has timer resolution 1 millisecond or better (as opposed to the typical 15ms that I’m used to seeing elsewhere).

    I ran these tests on one machine:

            var dt1 = DateTime.UtcNow;
            Thread.Sleep(11);
            var dt2 = DateTime.UtcNow;
            Console.WriteLine(dt2 - dt1);

    It outputs 00:00:00.0156006 (common knowledge – 15-16 milliseconds)

    However on my other machine, it outputs: 00:00:00.0110011

    Also, I ran this test:

            var sw = Stopwatch.StartNew();
            var start = DateTime.UtcNow;
            int changes = 0;
            int idle = 0;
            while (sw.ElapsedMilliseconds < 50)
            {
                var now = DateTime.UtcNow;
                if (now != start)
                {
                    start = now;
                    changes++;
                }
                else
                {
                    idle++;
                }
            }
     
            var elapsed = sw.Elapsed.ToString();
            Console.WriteLine(elapsed);
            Console.WriteLine(changes);
            Console.WriteLine(idle);
    

    and it printed:

    00:00:00.0500000
    3
    449714

    Which means it only updated 3 times within a 50 millisecond interval. On my new machine, this program printed:

    00:00:00.0500001
    50
    471655

    Which means that it updated at least every millisecond.

  • Kirill Osenkov

    A list of common HRESULT error codes

    • 3 Comments

    I was looking for error code –2146232797 (hex 0x80131623, which turned out to be what is thrown by Environment.FailFast) and I’ve stumbled upon this treasure:

    http://blogs.msdn.com/b/eldar/archive/2007/04/03/a-lot-of-hresult-codes.aspx

    Also, here’s a great blog about deciphering an HRESULT:

    http://blogs.msdn.com/b/heaths/archive/2005/07/21/441391.aspx

    And here's another good list from MSDN:

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

    I sincerely wish you to never ever need this knowledge...

  • Kirill Osenkov

    A Google Group for Augmented Programming

    • 0 Comments

    Josh Marinacci (from http://joshondesign.com) recently sparked a discussion about structured editing: http://joshondesign.com/2012/03/14/sacred-cows-2

    Jonathan Edwards has also blogged about this: http://alarmingdevelopment.org/?p=680#comment-59782

    It seems like there is continuous interest in structured editing.

    Jake Brownson had an idea to create a Google Group for us, structured editing and languages enthusiasts, and here it is:

    https://groups.google.com/forum/#!forum/augmented-programming

    The name “Augmented Programming” is neutral and temporary on purpose (to avoid preconceptions).

    I don’t know how much participation we’ll have, but it’s good to at least have a single central forum with the right folks involved. If you’re interested in structured editing, join in!

  • Kirill Osenkov

    Your Feedback about the Roslyn CTP NuGet Package?

    • 2 Comments

    As part of the Roslyn CTP in October 2011 we’ve published the core compiler and services binaries as a NuGet package:

    http://nuget.org/packages/roslyn

    Right now the Roslyn package adds references to the six core assemblies:

    1. Roslyn.Compilers
    2. Roslyn.Compilers.CSharp
    3. Roslyn.Compilers.VisualBasic
    4. Roslyn.Services
    5. Roslyn.Services.CSharp
    6. Roslyn.Services.VisualBasic

    I’d like to gather suggestions and other feedback about this package. How can we improve?

    The main piece of feedback we’ve heard so far is more fine-grained definition of what layers are needed:

    1. consumers don’t always need both C# and Visual Basic support
    2. consumers don’t always need the Services layer (Compiler layer is enough)

    Hence it would probably make sense to split the main package into several dependent packages, but then it gets a little complicated. We’d have to publish 8 packages and then the consumer could pick one “top” package which would then pull down all the dependencies it needs and nothing else):

    image

    It looks like we’re not the first to ask these questions:

    The consensus on this one seems to be that fine-granular is OK and as long as we publish updates to all subpackages simultaneously there shouldn’t be a problem.

    Your feedback and ideas about this issue and other suggestions are welcome!

  • Kirill Osenkov

    My Alma mater – BTU Cottbus in Germany

    • 1 Comments

    For my regular readers – this is a non-technical, non-work related post about my university BTU Cottbus and some current events related to it. I consider it important to publicly share my personal opinion on the matters to support my former professors, teachers, classmates and friends. This post is not endorsed by Microsoft and represents my private opinion only.   -- Kirill

    I consider myself fortunate to have studied at and graduated from the Brandenburg University of Technology (hereafter affectionally referred to as BTU) in Cottbus, Germany.

    imageimageimage

    It is a great university that welcomed me as an international student from Ukraine and provided me with a solid, high quality education.

    I studied computer science. The courses were great, modern, deeply technical and providing with the necessary foundations as well as practical applications. I’ve learned about structural programming (C++), object oriented programming (Java, .NET), functional programming (Haskell), pure computer science (algorithms, data structures, computability, turing machines, automata, languages), compilers (grammars, parsers, optimizers, semantics, lambda calculus), graphics, databases, OS fundamentals (threading, synchronization) and many many other things. I wrote an operating system (a toy one, but it booted and had threads!), a 3D fractal landscape generator in Haskell with OpenGL (anybody know what the $= operator means?), an AI (alpha-beta pruning) game engine in Prolog, a VPRO processor model in VHDL with an assembler and an interpreter, a garbage pickup schedule database in PHP and IBM DB2, and last, but not least, a structured editor for a subset of C#.

    The teachers and professors were very appproachable, loved their work, stayed late to help explain things, and often enjoyed a beer or two together with the students after lectures. The atmosphere was great.

    The facilities were good too, new buildings, projectors, computers, free internet, free web hosting, free source control, etc. Check out the new library for example:

     

    The university also provides students with valuable connections to start their future career. Through such a university-industry connection I found two wonderful summer internships with Microsoft in Redmond. After I’ve finished my thesis and graduated, I started fulltime here at Microsoft, which I consider is a great beginning that opens wide opportunities in life. I was interested in programming languages, editors and developer tools and found the best place to work on it!

    At the university, I’ve gained a lot of valuable professional and personal connections, found friends, learned new things, experienced life. The excellent German course for international students helped me learn German reasonably well in 6 months.

    To me, BTU is a university that provides deep and solid foundations to students of many disciplines – math, physics, computer science. It creates professionals who one day will grow up to become system changers and improve the world around them by creative thinking and applying what they’ve learned.

    And now they want to close this university as it exists today.

    There are plans and proposals from the ministry to dissolve BTU and the neighboring Hochschule Lausitz (another college in Brandenburg), and create a new university/college that is more targeted for environment/energy. As part of this, there are recommendations to close or severely trim the Department of Mathematics, Physics and join/trim the Departments of Computer Science and otherwise deprioritize math/computer science.

    Many of my friends among computer science teachers, professors and former classmates oppose this initiative, instead voting for preserving both colleges, and improving ties and collaboration between them, without sacrificing our deep specialization in math, physics and computer science. There is a lot of existing value that has accumulated in the current BTU structure over the years, it would be unwise to destroy all of it, throw away all the experience, fire (some? most?) teachers and professors and start from scratch.

    I would like to join and support this movement because I deeply believe that universities should not deprioritize fundamental things like math and computer science – we need to grow new generations of professionals who didn’t learn to code by “Teach yourself ThisYearsTechnologyX in 24 hours” kind of books.

    It is also especially important to attract and support women in math, physics and computer science, the way the ratio is skewed towards men nowadays is I think a real problem. And how do we attract more girls and boys to computer science, by closing well-established computer science departments and universities? Why fix what aint broken? Why be destructive before being constructive?

    Universities are a cradle of hope for the progress of our civilization, this is where we grow our best and brightest who will grow up and solve problems. We should do everything we can to foster and support them.

    image

    -----

    An meine Freunde, Alumni, Professoren, Mitarbeiter und Studierende der BTU, sowohl auch andere, die sich beteiligt fühlen – bitte äußern auch Sie Ihre Meinung zu diesem wichtigen Thema. Dieser Link http://studiy.tu-cottbus.de/projektwiki/gruppen:mittelbau:alumni_berichten erhält schon viele Berichte und Statements, aber nur wenn es viel mehr Stimmen gibt, die sich zur BTU bekennen, wird das Ministerium hoffentlich zuhören.

    -- Dipl.-Inf. Kirill Osenkov, Microsoft (from Redmond, WA, USA)

  • Kirill Osenkov

    New Tabula video

    • 0 Comments

    For those of you who follow me because of my interest in geometry, NumeracyWorks has released a new video about Tabula: http://www.youtube.com/watch?v=ZgkWtyfpi8Y

    The reason I’m so excited about it is that it’s a great showcase of the open-source geometry framework we’ve been developing at http://livegeometry.codeplex.com. I had no idea that one could build such amazing things with it. That’s the beauty of “seeding” an open-source project – it lives on without you!

    Since starting on Roslyn full time, I had to unfortunately de-prioritize my hobby work on Live Geometry for various reasons. First, I have to focus on one thing at a time to go deep and be productive. Second, Roslyn is a project of utmost importance, it’s The Right Thing To Do and I feel I need to give it my 100%.

    So it’s amazing to see that thanks to my contributors (mainly David) the framework lives on and brings fruition to such awesome products!

  • Kirill Osenkov

    Found my 1000th bug in Roslyn!

    • 3 Comments

    This might not seem like a big deal, but...

    1000BugsDev11

    Knowing that you guys won’t be seeing any of these bugs in production helps me sleep better at night :)

    So far, my favorite bug (nothing to be proud of, but I think it’s a fun one) is this:

    ContractFailure in FormattingContext.DebugCheckIntervalTree when formatting "War and Peace" by Leo Tolstoy

    Yes, Roslyn can parse, format and analyze large programs with errors. And believe me, the C# program War and Peace contains quite a few errors!

     

    Note: please don’t interpret this post as “Roslyn has 1000 bugs” :) On the contrary, I’m pretty happy with our rolling day-to-day quality, and folks who know me can appreciate what it says about the codebase.

  • Kirill Osenkov

    How to change the default command prompt color on Vista and above

    • 7 Comments

    If you like me don’t like the default green on black in the command prompt, you can change the default via registry:

    image

    Tip taken from here: http://www.pctools.com/guides/registry/detail/12/

    Update: and here’s a list of color values http://technet.microsoft.com/en-us/library/cc978716.aspx

  • Kirill Osenkov

    VS hangs for 1 minute on start debugging? Check for dead symbol paths!

    • 0 Comments

    I’ve just hit this again so I decided to share the solution in case anyone else hits this.

    Symptom: Visual Studio freezes for about a minute after you hit F5 (but before the app actually starts), then suddenly unfreezes and happily proceeds to launch the app.

    Cause: VS calls the Windows CreateFile function on one of the paths specified in Tools –> Options –> Debugging –> Symbols –> Symbol file (.pdb) locations and that location either doesn’t exist or can’t be accessed (e.g. due to misconfigured DNS settings).

    Solution: Check that all network paths in the list above can be accessed normally.

    If you launch ProcMon.exe before starting debugging and configure the filter to only monitor “devenv.exe”, Result = “BAD NETWORK PATH”, it should show you which CreateFile call causes a network timeout.

    Sources:

    * http://support.microsoft.com/kb/951336
    * http://social.msdn.microsoft.com/forums/en/vsdebug/thread/1ede20ce-b236-4361-8dcb-04189b607152

  • Kirill Osenkov

    DateTime.UtcNow is generally preferable to DateTime.Now

    • 9 Comments

    This seems to be commonly known and accepted best practice to use DateTime.UtcNow for non-user facing scenarios such as time interval and timeout measurement.

    I’ve just done an audit of the Roslyn codebase and replaced most DateTime.Now calls with DateTime.UtcNow. I thought it’d be useful to post my changeset description here (although none of it is new – I just summarize some common knowledge readily available in the sources linked below).

    ====

    Replacing DateTime.Now with DateTime.UtcNow in most cases.

    We should be using DateTime.Now only in user-facing scenarios. It respects the timezone and Daylight Savings Time (DST), and the user feels comfortable when we show them the string that matches their wall clock time.

    In all other scenarios though DateTime.UtcNow is preferable.

    First, UtcNow usually is a couple of orders of magnitude faster, since Now is basically first calling UtcNow and then doing a very expensive call to figure out the time zone and daylight savings time information. Here’s a great chart from Keyvan’s blog (modified to avoid allocations of the Stopwatch object):

    image

    Second, Now can be a big problem because of a sudden 1-hour jump during DST adjustments twice a year. Imagine a waiting loop with a 5-sec timeout that happens to occur exactly at 2am during DST transition. The operation that you expect to timeout after 5 sec will run for 1 hour and 5 seconds instead! That might be a surprise.

    Hence, I'm replacing DateTime.Now with DateTime.UtcNow in most situations, especially polling/timeout/waiting and time interval measurement. Also, everywhere where we persist DateTime (file system/database) we should definitely be using UtcNow because by moving the storage into a different timezone, all sorts of confusion can occur (even "time travel", where a persisted file can appear with a future date). Granted, we don't often fly our storage with a supersonic jet across timezones, but hey.

    For precise time interval measurements we should be using System.Diagnostics.StopWatch which uses the high resolution timer (QueryPerformanceCounter). The resolution of both DateTime.Now and DateTime.UtcNow is very low – about 10 ms – this is a huge time interval!

    For a cheap timestamp, we should be generally using Environment.TickCount - it's even faster than DateTime.UtcNow.Ticks.

    I'm only leaving DateTime.Now usages in test code (where it's never executed), in the compiler Version parsing code (where it's used to generate a minor version) and in a couple of places (primarily test logging and perf test reports) where we want to output a string in a local timezone.

    Sources:

    * http://www.keyvan.ms/the-darkness-behind-datetime-now
    * http://stackoverflow.com/questions/62151/datetime-now-vs-datetime-utcnow
    * http://stackoverflow.com/questions/28637/is-datetime-now-the-best-way-to-measure-a-functions-performance

  • Kirill Osenkov

    Install-Package Roslyn

    • 1 Comments

    I am happy to announce that the core C# and VB compiler assemblies from our first Roslyn CTP are now published as a NuGet package! The package name is... drumroll... ‘Roslyn’!

    Aside: If you haven’t tried out NuGet yet, NuGet is definitely worth a try – it’s a simple to use but powerful package/library/dependency manager, and right now it’s the top free download in the Visual Studio 2010 Extension Manager:

    image

    Once you’ve installed NuGet, you can add the Roslyn package as a dependency to your project either using the Manage NuGet Packages dialog:

    image

    image

    or the PowerShell-based command line called the Package Manager Console:

    image

    The Roslyn package contains the six core assemblies:

    1. Roslyn.Compilers.dll
    2. Roslyn.Compilers.CSharp.dll
    3. Roslyn.Compilers.VisualBasic.dll
    4. Roslyn.Services.dll
    5. Roslyn.Services.CSharp.dll
    6. Roslyn.Services.VisualBasic.dll

    These are the exact binaries that we’ve shipped in the October 2011 CTP, packaged for your convenience. Note that the remaining content of the CTP, such as the IDE and refactoring support is not part of the package – you will still need the CTP to gain access to those.

    Also please keep in mind that the license doesn’t allow you to redistribute the Roslyn binaries with your projects at this time. But that’s just common sense – the compilers are still at a pretty early (preview-only) stage with about half the language not supported yet. You wouldn’t want to ship these binaries to customers just yet, because we don’t even guarantee that whatever compiles produces correct IL!

    I invite you to use the Roslyn forum if you have questions or feedback. Thanks!

  • Kirill Osenkov

    Roslyn CTP

    • 5 Comments

    For the past year and a half or so I’ve been working on the QA team for the Roslyn project. The goal of our project is (simply put) to make our managed compilers and language services actually managed :-)

    I’m happy to announce that we’ve released our first CTP today and it is available for immediate download at http://msdn.com/roslyn.

    I’ve posted a more detailed overview of the release over on the Visual Studio blog. Now that we can actually talk about our work, I expect to blog more about Roslyn and otherwise keep in touch with the developer community. I’ll be also tweeting more about Roslyn (@KirillOsenkov). I suggest that we use the #RoslynCTP hashtag on Twitter for Roslyn-related discussions (#Roslyn is already taken by the actual city of Roslyn).

    We will also be participating on the Roslyn forum, and closely monitoring the Connect bugs and suggestions.

    Below I want to show a few demos of what Roslyn can do. I’ll start with excerpts from one of the samples that we ship (APISampleUnitTests) – a set of unit-tests that demonstrates the usage of the compiler API. To me, there’s no better way to learn an API surface than by reading the unit-tests that cover it.

    Have you ever needed a full-fidelity, high performance C# parser?

    [TestMethod]
    public void TextParseTreeRoundtrip()
    {
        string text = "class C { void M() { } } // exact text round trip, including comments and whitespace";
        SyntaxTree tree = SyntaxTree.ParseCompilationUnit(text);
        Assert.AreEqual(text, tree.ToString());
    }

    Or perhaps you prefer VB?

    <TestMethod()>
    Sub TextParseTreeRoundtrip()
        Dim code =
    <code>
    Class C
      Sub M()
      End Sub
    End Class ' exact text round trip, including comments and whitespace
    </code>.GetCode()
     
        Dim tree = SyntaxTree.ParseCompilationUnit(code)
        Assert.AreEqual(code, tree.Text.ToString())
    End Sub
    

    You can also parse a stand-alone expression:

    ExpressionSyntax expression = Syntax.ParseExpression("1 + 2");
    

    Want to do LINQ queries over your code?

    [TestMethod]
    public void FindNodeUsingQuery()
    {
        string text = "class C { void M(int i) { } }";
        SyntaxNode root = Syntax.ParseCompilationUnit(text);
        var parameterDeclaration = root
            .DescendentNodes()
            .OfType<ParameterSyntax>()
            .First();
        Assert.AreEqual("i", parameterDeclaration.Identifier.ValueText);
    }
    

    Or transform your code using Visitors?

    [TestMethod]
    public void TransformTreeUsingSyntaxRewriter()
    {
        string text = "class C { void M() { } int field; }";
        SyntaxTree tree = SyntaxTree.ParseCompilationUnit(text);
        SyntaxNode newRoot = new RemoveMethodsRewriter().Visit(tree.Root);
        Assert.AreEqual("class C { int field; }", newRoot.GetFullText());
    }
     
    private class RemoveMethodsRewriter : SyntaxRewriter
    {
        protected override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax node)
        {
            return null;
        }
    }

    What about executing custom code (scripting)?

    [TestMethod]
    public void SimpleEvaluationUsingScriptEngine()
    {
        ScriptEngine engine = new ScriptEngine();
        int result = engine.Execute<int>("1 + 2");
        Assert.AreEqual(3, result);
    }
    

    Or compiling a program end-to-end?

    [TestMethod]
    public void EndToEndCompileAndRun()
    {
        var expression = "6 * 7";
        var text = @"public class Calculator
    {
    public static object Evaluate()
    {
    return $;
    } 
    }".Replace("$", expression);
     
        var tree = SyntaxTree.ParseCompilationUnit(text);
        var compilation = Compilation.Create(
            "calc.dll",
            options: new CompilationOptions(assemblyKind: AssemblyKind.DynamicallyLinkedLibrary),
            syntaxTrees: new[] { tree },
            references: new[] { new AssemblyFileReference(typeof(object).Assembly.Location) });
     
        Assembly compiledAssembly;
        using (var stream = new MemoryStream())
        {
            EmitResult compileResult = compilation.Emit(stream);
            compiledAssembly = Assembly.Load(stream.GetBuffer());
        }
     
        Type calculator = compiledAssembly.GetType("Calculator");
        MethodInfo evaluate = calculator.GetMethod("Evaluate");
        string answer = evaluate.Invoke(null, null).ToString();
     
        Assert.AreEqual("42", answer);
    }
    

    Have you ever wanted to write your .bat files in C#, with IntelliSense and full compiler support?

    image

    image

    There’s more. Stay tuned!

  • Kirill Osenkov

    How to get DTE from Visual Studio process ID?

    • 4 Comments

    DTE is an automation framework that is used to programmatically control Visual Studio, often from another process. It internally uses COM remoting to execute commands from another process on the VS UI thread.

    A while back I have written about How to start Visual Studio programmatically and get the DTE object to control the devenv.exe process. But how to get the DTE object to automate an already running Visual Studio instance? Or how to get the DTE object to automate Visual Studio started from an experimental hive (using the /rootsuffix command line option)?

    Here’s the code (need to reference EnvDTE, which is a PIA, no pun intended):

    using System;
    using System.Runtime.InteropServices;
    using System.Runtime.InteropServices.ComTypes;
    using EnvDTE;
     
    public class AutomateVS
    {
        [DllImport("ole32.dll")]
        private static extern int CreateBindCtx(uint reserved, out IBindCtx ppbc);
     
        public static DTE GetDTE(int processId)
        {
            string progId = "!VisualStudio.DTE.10.0:" + processId.ToString();
            object runningObject = null;
     
            IBindCtx bindCtx = null;
            IRunningObjectTable rot = null;
            IEnumMoniker enumMonikers = null;
     
            try
            {
                Marshal.ThrowExceptionForHR(CreateBindCtx(reserved: 0, ppbc: out bindCtx));
                bindCtx.GetRunningObjectTable(out rot);
                rot.EnumRunning(out enumMonikers);
     
                IMoniker[] moniker = new IMoniker[1];
                IntPtr numberFetched = IntPtr.Zero;
                while (enumMonikers.Next(1, moniker, numberFetched) == 0)
                {
                    IMoniker runningObjectMoniker = moniker[0];
     
                    string name = null;
     
                    try
                    {
                        if (runningObjectMoniker != null)
                        {
                            runningObjectMoniker.GetDisplayName(bindCtx, null, out name);
                        }
                    }
                    catch (UnauthorizedAccessException)
                    {
                        // Do nothing, there is something in the ROT that we do not have access to.
                    }
     
                    if (!string.IsNullOrEmpty(name) && string.Equals(name, progId, StringComparison.Ordinal))
                    {
                        Marshal.ThrowExceptionForHR(rot.GetObject(runningObjectMoniker, out runningObject));
                        break;
                    }
                }
            }
            finally
            {
                if (enumMonikers != null)
                {
                    Marshal.ReleaseComObject(enumMonikers);
                }
     
                if (rot != null)
                {
                    Marshal.ReleaseComObject(rot);
                }
     
                if (bindCtx != null)
                {
                    Marshal.ReleaseComObject(bindCtx);
                }
            }
     
            return (DTE)runningObject;
        }
     
        static void Main(string[] args)
        {
            var devenv = System.Diagnostics.Process.Start("devenv.exe");
     
            DTE dte = null;
            do
            {
                System.Threading.Thread.Sleep(2000);
                dte = GetDTE(devenv.Id);
            }
            while (dte == null);
     
            dte.ExecuteCommand("View.CommandWindow");
            dte.StatusBar.Text = "Hello World!";
            System.Threading.Thread.Sleep(2000);
            dte.ExecuteCommand("File.Exit");
            devenv.WaitForExit();
            Marshal.ReleaseComObject(dte);
        }
    }
    

    When Visual Studio starts (regardless if it was passed the /rootsuffix command line argument), it places itself onto the Running Object Table (aka ROT). We know the moniker that the Visual Studio process will use to identify itself (it’s !VisualStudio.DTE.10.0:1234, where 1234 is the devenv.exe process ID). We then enumerate though all the objects in the ROT and find the one with the right moniker.

    Then you can just keep using the DTE object as if you’re writing a macro (Visual Studio macros also use DTE to automate VS).

  • Kirill Osenkov

    How Microsoft Names Releases… And What You Can Do About It

    • 0 Comments

    image

    Microsoft® SQL Server® 2008 R2 SP1 Feature Pack CTP1.

    Scott Hanselman wrote a blog post called Request for Comments: Issues with .NET and Microsoft Product Versioning. He welcomes your feedback either in his blog comments or a Twitter Poll for you to spread around.

  • Kirill Osenkov

    In ngen’ed assemblies, static field initializers don’t run until the field is first accessed

    • 3 Comments

    Interesting fact that I discovered today: usually, static field initializers run whenever the parent type is first loaded. However when you ngen the assembly, apparently you can load the type and work with it – static field initializers will only be executed immediately before you actually access the field.

    I’ve run into this by having a static Stopwatch timer = Stopwatch.StartNew(); in one of my types. It was supposed to measure an application’s startup time, but I noticed that after NGEN’ing the assembly the timer always returned a value close to 0.

    Here’s the code to verify this behavior:

    using System;
     
    class Program
    {
        private static int field = Initialize("Field initializer");
     
        static void Main(string[] args)
        {
            Initialize("Main");
            field = 1; // touch the field
        }
     
        private static int Initialize(string message)
        {
            Console.WriteLine(message + ": " + DateTime.Now.Ticks.ToString());
            return 0;
        }
    }

    This works the same for .NET 4.0 SP1 for Debug/Release and x86/x64. I didn’t try other frameworks/OS/platforms.

    Here’s the output from the console:

    E:\>NgenedStaticFieldInitializers.exe
    Field initializer: 634462768999291588
    Main: 634462768999321594
    
    E:\>NgenedStaticFieldInitializers.exe
    Field initializer: 634462769013544438
    Main: 634462769013574444
    
    E:\>ngen install NgenedStaticFieldInitializers.exe
    Microsoft (R) CLR Native Image Generator - Version 4.0.30319.1
    Copyright (c) Microsoft Corporation.  All rights reserved.
    Installing assembly E:\NgenedStaticFieldInitializers.exe
    1>    Compiling assembly E:\NgenedStaticFieldInitializers.exe (CLR v4.0.30319) .
    ..
    1>NgenedStaticFieldInitializers, Version=1.0.0.0, Culture=neutral, PublicKeyToke
    n=null 
    
    E:\>NgenedStaticFieldInitializers.exe
    Main: 634462769095630852
    Field initializer: 634462769095660858
    
    E:\>NgenedStaticFieldInitializers.exe
    Main: 634462769108903506
    Field initializer: 634462769108933512
  • Kirill Osenkov

    Tabula

    • 7 Comments

    Another announcement for geometry enthusiasts today. David Hartmann, an experienced math teacher and my active co-developer on the Live Geometry project, has released a professional geometry learning software: Tabula.

    http://numeracyworks.com/

    Tabula is written in Silverlight 4 and is based on our Live Geometry engine, however it takes it way further in terms of features, usability and being a great professional product for students, teachers and hobbyists. Tabula introduces unique capabilities for interactive “paper folding”, taping, cutting and rearranging, as well as close-to-real-life tools like eraser, marker, compass, ruler, protractor, and so on. I encourage you to watch this short video that gives a great overview of Tabula’s possibilities:

    Tabula

    http://www.youtube.com/watch?v=9PM_PzQqK6Q

    I’ll also allow myself to steal some of David’s thunder and post the links to screenshots here:


    Compass and Mark on Segment

    Ruler and Measure of a Side

    Protractor and Measured Angle

    Folded Square

    Sine Function

    Constructed Pentagon

    Magic Square

    Pentominos

    Sierpinski's Triangle

    Custom Settings and Inspector Visible

    I’m very excited and enthusiastic about Tabula and I hope it will grow and develop. Dear readers, I’d like to ask you a personal favor at this time: if you like the project and would like to show your support, please help David spread the news! As always, let him or me know your opinion/questions/feedback. Thanks!

  • Kirill Osenkov

    Live Geometry for Windows Phone 7

    • 4 Comments

    I was really curious to try to write an app for WP7, but I didn’t have a whole lot of ideas. It’s hard to come up with something original when so many apps are already out there. And I don’t have capacity for a large complex app (if I had time for a very large app, I would write a decent GPS navigation software because it seems that Tomtom and Garmin aren’t in a rush to create a WP7 version of their systems).

    Nevertheless, since I have some experience with math educational software, I decided to leverage my http://livegeometry.codeplex.com open-source project to try and create an app with at least some educational value. Writing a full-blown live geometry app on the phone didn’t seem plausible to me since the screen real estate is very limited and I couldn’t figure out how to make the interaction usable. However it dawned on me that a little “fun facts” or “geometry gems” gallery would look quite nice on the phone.

    So here it is: http://social.zune.net/redirect?type=phoneApp&id=5e8194b7-d0ea-df11-9264-00237de2db9e

    (or just search for “Live Geometry” on Marketplace).

    It’s a collection of 35 interactive geometry drawings each of which illustrates a certain fact or a theorem of elementary geometry. As always you can drag the points around to experiment with the construction. Here are the screenshots that you will also see on the marketplace:

    StartSquaresAroundRhombusPythagoreanTheoremParabolaGraph

    CircumscribedCircleBezier

  • Kirill Osenkov

    Improved HTML Copy in the latest Productivity Power Tools

    • 3 Comments

    Executive summary: HTML Copy is an extension for Visual Studio 2010 (part of Productivity Power Tools) that automatically copies source code from the Visual Studio editor to clipboard in HTML format (in addition to the existing TEXT and RTF formats), preserving font and color information. It does so automatically every time you press Ctrl+C or otherwise invoke the Edit.Copy command, so there is no explicit way to invoke the feature (it has no UI of its own).

    In the latest release: all font and background color information is now correctly written to HTML, dark schemes such as those from http://studiostyl.es are now correctly supported. Format of the output markup is now customizable via a Tools Options page.

    Hint: if you don’t want to read all the long details below, but still interested or have a question, there’s an FAQ at the end of this post. Don’t miss it!

    Also see my previous posts about HTML Copy:

    Configuring the output via the Tools Options page

    I guess the biggest improvement in this version is that I finally added a Tools Options page that lets you customize the HTML markup that ends up on the clipboard:

    Tools Options page

    You can select how the snippet is prefixed (arbitrary markup, could be anything, e.g. custom JavaScript etc.) By default, I use <pre style=”...”>, because after looking at various blogs this is the most common way to format code. Moreover, you can insert the actual values for the font, foreground color and background color in curly braces. If you don’t want to have the values embedded, just remove the macro in curlies and hardcode your own value.

    Format for the colorized spans – use CSS or embed styles directly

    Colorized spans in code are encoded using the <span> tag – you can’t change that.

    However, you can choose whether to use CSS for classes (EmitSpanClass). If you select this one, highlighted spans from the editor will add the actual classification type of the span into the resulting HTML markup:

    <span class="keyword">public</span>

    The classification type is what the language service actually classifies the token as, so the full fidelity information from the compiler is preserved in your output HTML. For instance, DayOfWeek.Friday will be output as:

    <span class="User Types(Enums)">DayOfWeek</span><span class="operator">.</span><span class="identifier">Friday</span>

    Then you just have to define your own CSS for the various classification types that the compiler uses, and your code will be correctly colorized in the browser.

    If you don’t want to use separate CSS styles however, you have the option to embed the font and color information directly in your HTML. Set EmitSpanStyle to true (and EmitSpanClass to false), and you will produce stand-alone, independent HTML that doesn’t need any CSS:

    <span style="color:blue;">public</span>
    <span style="color:#2b91af;">DayOfWeek</span>.Friday

    Preserving full language fidelity from the Visual Studio editor

    HTML Copy has an advantage over other code formatting tools that colorize code for the web using their own, simple rules (often RegEx based). HTML Copy colorizes code exactly how Visual Studio editor displays it. Also, this works just as well for other code formats, such as HTML, VB, F# etc. As long as the VS editor has classified the text, we just grab that information and output it to clipboard while preserving the exact classification types and classification format definitions.

    The controversy around the <br> tag

    You have an option to replace line breaks with the <br> tag. Why? I had done some research to see how different RSS readers present formatted code and it turns out, if you use Outlook RSS Feed Reader, it has a bug where it just ignores line break characters inside <pre> tags and lumps all the code onto one long line which is word-wrapped. I’ve let the Office team know about the bug, but in the meanwhile, I decided to provide the option to use the <br> tag instead of line break in HTML. Downside of it is that in HTML source, your code looks like one long line, but the good news is that RSS Reader in Outlook then correctly displays the text. Other readers also correctly display <BR> tags inside <PRE> tags, so we should be good here, no?

    No.

    Internet Explorer doesn’t copy the <br> as a line break when selecting the code in the page and copying it to clipboard. Suppose you’re reading a blog and you would like to copy the code from the webpage. You select it, paste into notepad and you get one long line! That’s why, if you want your readers to be able to copy your code correctly from a webpage in IE, don’t use the <BR> tag, use the line break in HTML. I’ve let the IE team know about the bug (preserve line breaks when copying <BR> inside <PRE> to clipboard), but they didn’t fix it in time before IE9 shipped.

    The controversy around the space and &nbsp;

    A similar “surprise” was awaiting me when I installed Windows Live Writer 2011 to test HTML Copy with their latest version. Live Writer used to be the tool that I LOVED, because it was simple, did the right thing and was a pleasure to use.

    Enter Windows Live Writer 2011.

    When pasting HTML from clipboard using Ctrl+Alt+V, DOWN, ENTER, it apparently thinks that you pasted code from Word, and their special algorithm kicks in that is supposed to “fix” the tangled Word formatting. In reality however, they take the clean and well-formed HTML that I put to clipboard and mess it up beyond any recognition. In particular, if you were using spaces for indentation in your code, it will at random insert inexplicable &nbsp; all over the place. I’ve found that if I replace all my spaces with &nbsp; myself, then Live Writer at least has some mercy for the HTML markup and while still mangled, it displays more or less correctly in the browser, so I included the option. Naturally, I’ve done due diligence and informed the Live Writer team about this unfortunate behavior regression. Let’s see if they fix it as promptly as the Internet Explorer team did (ha-ha, my bitter sarcasm!).

    Bug fixes

    This release has a few bug fixes that I’ve accumulated from customer reports (thanks everyone for your feedback!). One good news is that I now correctly preserve the background color and font information, so the tool should now correctly work for folks with a dark scheme (sorry for the white on white stupidity – I should have known better!).

    Copy from Remote Desktop and other Windows Clipboard oddities

    One major thing that Ameen from the editor team helped me fix is that sometimes Copy just didn’t work inside Remote Desktop sessions. If you have HTML Copy installed, and press Ctrl+C inside remote desktop, and the code doesn’t get copied to clipboard – please just try copying it again a few times.

    The story (Raymond Chen style). Windows clipboard obviously needs to be available to all the processes, which, naturally, run concurrently. I would have thought that they have some sort of a reader-writer lock, a monitor, semaphore – anything. Well, no. If a process tries to access clipboard while the clipboard is already open, it just fails with CLIPBRD_E_CANT_OPEN. A good description of this can be found here or here for example.

    In brief, if you copy stuff to clipboard in remote desktop, shortly after you’re done, it will open the clipboard again to synchronize it back to the host machine. About the same time however, I come in and try to open the clipboard too (because I want to augment the TEXT and RTF formats already there with the new HTML format). Obviously, we both fail, and what do we both do? We both go sleep 100ms. Yes, that’s how the WinForms team and the WPF team worked around the lack of proper synchronization in Windows Clipboard. They retry 10 times and sleep for 100 milliseconds in between. The problem now is: they all wake up and try again at the same time. Better solution here would be at least to sleep a random number of milliseconds (module timer granularity), but alas this is not the case here.

    The way I wrote HTML Copy originally is that it was listening to the Edit.Cut and Edit.Copy VS commands, and after VS has put TEXT and RTF to clipboard, I happened to additionally put HTML on clipboard in a second transaction. Now I just completely suppress Visual Studio’s handling of the Cut and Copy commands, and copy all the formats, TEXT, RTF and HTML in one fell swoop. This should hopefully alleviate the problems connected with copying over remote desktop.

    The next most requested feature (not there yet)

    The request I’ve been hearing the most is to add some sort of a command, that wouldn’t put HTML to clipboard in a separate clipboard format parallel to text and RTF, but instead put the HTML tags to clipboard directly in text format, so that you can paste source yourself to a simple text box such as the one in Wordpress or other web-based tools.

    Obviously I can’t copy HTML markup to plain text clipboard during normal operation, because this would break copying code around in VS during programming (on second thought – hmm, maybe not such a bad idea after all??!)

    So I guess I need to mentally prepare myself for adding an actual Visual Studio menu item to explicitly copy HTML markup to clipboard in plaintext format. Let’s hope I get around to it before the next update of the Productivity Power Tools.

    FAQ

    How do I use HTML Copy?

    Provided you have installed Visual Studio 2010 and Productivity Power Tools, there are only two simple sides to it – Produce HTML and Consume HTML. You Produce HTML (or simply put it on clipboard) by copying code in the editor as you normally would (most people prefer Ctrl+C). You Consume HTML by pasting it in a program which has a “Paste Special” feature, such as Word, Outlook, OneNote or Windows Live Writer, and selecting HTML format instead of plain text format.

    How do I paste code in Windows Live Writer?

    Ctrl+Alt+V (or Ctrl+Shift+V on older versions) will pop up the Paste Special dialog. Then, select Keep Formatting (DOWN ARROW) and ENTER (if you don’t see Keep formatting there, it means HTML Copy didn’t work). Then you can switch to the Source view and actually examine the HTML. Caveat: Windows Live Writer 2011 mangles the HTML the moment you paste it, so please don’t blame me – I produce clean well-formed HTML without redundant tags. I also don’t use <font> tags, so if you see a <font> tag, it’s not me!

    How do I get the source for the HTML markup?

    You need a tool that lets you examine the clipboard, such as Clipview by Peter Büttner:

    image

    Don’t forget to push the View button in the top-left corner – the tool doesn’t refresh automatically! If you know a better way, please let me know!

    How does this compare to other tools?

    There are plenty existing tools out there to let you format code on your blog. Here are some links:

    SyntaxHighlighter by Alex Gorbatchev is very nice and seems to be popular. One minor thing with it is that it requires JavaScript (not all readers support it). Code will still display decently though, so it’s not a big issue. Another downside of tools like this – they do their own colorization, and don’t preserve the exact classification of the compiler. Thus, they’re less precise. But again, this is very minor – it works reasonably well in the general case.

    CopySourceAsHtml seems to be very nice (and HTML Copy is essentially the same thing, but Colin was first!) He did a fantastic job with the APIs we exposed at the time. We both colorize code correctly (like VS does), but we don’t output as neat functionality as SyntaxHighlighter (ability to copy/print code for example, which requires JavaScript). I also don’t support line numbers in HTML Copy.

    Paste from VisualStudio by Douglas Stockwell is a Windows Live Writer plug-in that takes RTF from clipboard and converts it to HTML. An advantage is that it preserves correct coloring from the editor, downside is that it’s only for Live Writer.

    Why did you decide to write yet another tool like this, with plenty of good tools already out there?

    Architecture. With the brand new editor in Visual Studio 2010, it’s design is so nice and pluggable, it allows extensions to easily add whatever formats to clipboard. However text and RTF were implemented in the box, but HTML wasn’t. I really wanted a tool like this to be in the box, so I looked around. Unfortunately, the implementation of CopySourceAsHtml (the best tool I’ve found) didn’t take advantage of the new editor APIs so I decided to write my own. Since Productivity Power Tools seemed like a good ship vehicle to give my implementation proper testing, I decided to do just that. Maybe if the tool is good enough one day, we’ll put this in the box.

    What are the known bugs and feature requests?

    1. Again, the biggest is showing raw HTML markup to the user.
    2. Then I have a request from Tomáš Skála to normalize indentation (should be something along the lines (no pun intended!) of while(lines.All(line => line.StartsWithSpace())) lines = lines.Select(line => line.TrimFirstSpace())
    3. Then I have a bug report from csrowell where Ctrl+L on two non-fully selected lines doesn’t fully delete both lines

    As always, please let me know your questions and comments if any. Thanks!

  • Kirill Osenkov

    Running .NET applications in-process using AppDomains

    • 6 Comments

    When testing a compiler for a managed language a very convenient end-to-end testing technique is to compile a test program, then run it and verify that it gives the expected output. Not only you cover all parts of the compiler in this manner (parser, binder and emitter), but also you verify that your compiler produces correct IL (otherwise the CLR won’t load and verify your assembly) and your final program has the expected behavior (output has to match).

    One downside is that if you have 50,000 test programs, you have to pay the process startup cost and the CLR startup cost 50,000 times. AppDomains to the rescue – they were originally designed as lightweight managed processes, so why not use them as such?

    To demonstrate this approach, we’re going to write a .NET program that can run any .NET Console application, intersept its output to the Console, and print it out for demo purposes. First of all, let’s create a C# console application that prints out “Hello World” and save it as Program.exe. Then let’s create a sample “verifier” program that will start and run Program.exe without spinning up a separate process and a separate CLR instance:

    using System;
    using System.IO;
    using System.Reflection;
     
    namespace AppDomainTools
    {
        public class Launcher : MarshalByRefObject
        {
            public static void Main(string[] args)
            {
                TextWriter originalConsoleOutput = Console.Out;
                StringWriter writer = new StringWriter();
                Console.SetOut(writer);
     
                AppDomain appDomain = AppDomain.CreateDomain("Loading Domain");
                Launcher program = (Launcher)appDomain.CreateInstanceAndUnwrap(
                    typeof(Launcher).Assembly.FullName,
                    typeof(Launcher).FullName);
     
                program.Execute();
                AppDomain.Unload(appDomain);
     
                Console.SetOut(originalConsoleOutput);
                string result = writer.ToString();
                Console.WriteLine(result);
            }
     
            /// <summary>
            /// This gets executed in the temporary appdomain.
            /// No error handling to simplify demo.
            /// </summary>
            public void Execute()
            {
                // load the bytes and run Main() using reflection
                // working with bytes is useful if the assembly doesn't come from disk
                byte[] bytes = File.ReadAllBytes("Program.exe");
                Assembly assembly = Assembly.Load(bytes);
                MethodInfo main = assembly.EntryPoint;
                main.Invoke(nullnew object[] { null });
            }
        }
    }
    

    This approach is especially beneficial if you have to run a lot of small programs – you save a lot on process startup costs and CLR startup costs. Note that I’m representing an assembly as a plain byte array – this allows us to avoid disk I/O if the assembly was just compiled and wasn’t even saved to disk, so you can compile and run it immediately, without ever writing the compiler’s output to disk.

    Also note that Launcher inherits from MarshalByRefObject – this allows us to pass data back and forth across AppDomain boundaries. If you like, just create an instance field in the Launcher class and it will get automatically serialized/deserialized when it passes through the DoCallback invocation point.

  • Kirill Osenkov

    Fix available for the VS 2010 context menu scrolling issue

    • 0 Comments

    http://blogs.msdn.com/b/visualstudio/archive/2010/10/14/hotfixes-available-for-scrolling-context-menu-problem.aspx

    Sorry we didn’t fix the bug before RTM, but better late than never... Hopefully the fix works fine for everyone.

  • Kirill Osenkov

    C# Syntax All-In-One file, attempt 3

    • 12 Comments

    OK, my dear readers, I’ve finally had a chance to incorporate your invaluable feedback (really, this is helpful to me in my work) from the previous two attempts to produce another iteration of the Most Complete C# Syntax Frankenstein Junkyard. Let’s see if we are still missing any syntax construct (that hits a new codepath in the parser, not including error tolerance cases):

    #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 Y = 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<[System.Obsolete()] out T, in K> () where T : struct
    ;

       
    public unsafe partial class A
    : C, I
        {
            [DllImport(
    "kernel32", SetLastError = true
    )]
           
    static extern bool CreateDirectory(string
    name, SecurityAttribute sa);

           
    private const int global = int
    .MinValue - 1;

            [
    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;
               
    int
    minInt32Value = -2147483648;
               
    int
    minInt64Value = -9223372036854775808L;

               
    bool
    @bool;
               
    byte
    @byte;
               
    char @char = 'c', \u0066 = '\u0066', hexchar = '\x0130', hexchar2 = (char
    )0xBAD;
               
    string \U00000065 = "\U00000065"
    ;
               
    decimal
    @decimal = 1.44M;
                @decimal = 1.2m;
               
    dynamic
    @dynamic;
               
    double @double = M
    .PI;
                @double = 1d;
                @double = 1D;
                @double = -1.2e3;
               
    float
    @float = 1.2f;
                @float = 1.44F;
               
    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;
                where = 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
    [, ,] cube = { { { 111, 112, }, { 121, 122 } }, { { 211, 212 }, { 221, 222 } } };
               
    int
    [][] jagged = { { 111 }, { 121, 122 } };
               
    int[][,] arr = new int[5][,]; // as opposed to new int[][5,5]
                arr[0] = new int[5,5];  // as opposed to arr[0,0] = new int[5];
                arr[0][0,0] = 47;
               
    int[] arrayTypeInference = new
    [] { 0, 1, };
               
    switch
    (3) { }
               
    switch
    (i)
                {
                   
    case
    0:
                   
    case
    1:
                        {
                           
    goto case
    2;
                        }
                   
    case
    2 + 3:
                        {
                           
    goto default
    ;
                           
    break
    ;
                        }
                   
    default
    :
                        {
                           
    return
    ;
                        }
                }
               
    while
    (i < 10)
                {
                    ++i;
                   
    if (true) continue
    ;
                   
    break
    ;
                }
               
    do
                {
                    ++i;
                   
    if (true) continue
    ;
                   
    break
    ;
                }
               
    while
    (i < 10);
               
    for (int
    j = 0; j < 100; ++j)
                {
                   
    for
    (;;)
                    {
                       
    for (int
    i = 0, j = 0; i < length; i++, j++) { }
                       
    if (true) continue
    ;
                       
    break
    ;
                    }
                }
                label:
               
    goto
    label;
                label2: ;
               
    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 (A a = new A(), b = new
    A())
               
    using
    (BeginScope())
                   
    return
    ;
               
    yield return this
    .items[3];
               
    yield break
    ;
               
    fixed (int* p = stackalloc int
    [100], q = &y)
                {
                    *intref = 1;
                }
               
    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() };
                query =
    from c in
    customers
                       
    select c into
    d
                       
    select
    d;
            }
            ~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
    { E += Handler; E -= Handler; }
            }
           
    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>> where
    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;
                        M(A<B, C>(5));
                    }
                };
            };
        };

       
    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;
                };
               
    Func<int, int, int
    > f2 = (a, b) => 0;
                f2 = (
    int a, int
    b) => 1;
               
    Action
    a = Blah;
                f2 = () => {};
                f2 = () => {;};
            }

           
    delegate
    Recursive Recursive(Recursive r);
           
    delegate
    Recursive Recursive<A,R>(Recursive<A,R> r);

           
    public Type
    Foo
            {
                [
    Obsolete("Name", error = false
    )]
               
    get
                {
                   
    var result = typeof(IEnumerable<int
    >);
                   
    var t = typeof(int?) == typeof(Nullable<int
    >);
                    t =
    typeof(IEnumerable<int
    ?[][][]>);
                   
    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);
                Params(
    ref c, out
    c);
            }
           
    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; public void ThisAccess() { this = this; } }
        }
    }
  • Kirill Osenkov

    Multiple variables in a using statement

    • 5 Comments

    Here’s a simple file copy program:

    using System;
    using
    System.IO;

    public class FileCopy
    {
       
    private static void Main(string
    [] args)
        {
           
    if
    (args.Length != 2)
            {
               
    Console.WriteLine("Usage: filecopy <source> <destination>"
    );
               
    return
    ;
            }

            Copy(args[0], args[1]);
        }

       
    private static void Copy(string source, string
    destination)
        {
           
    const int
    BufferSize = 64 * 1024;
           
    using (FileStream input = File.OpenRead(source), output = File
    .OpenWrite(destination))
            {
               
    var buffer = new byte
    [BufferSize];
               
    int
    bytesRead;
               
    while ((bytesRead = input.Read(buffer, 0, BufferSize)) != 0)
                {
                    output.Write(buffer, 0, bytesRead);
                }
            }
        }
    }

    I’ve only recently learned that you can use multiple local variable declarators in the using statement, separated by comma, as long as they are of the same type. In the spec, section 8.13 (The using Statement), it says:

    using-statement:

    using ( resource-acquisition ) embedded-statement

    resource-acquisition:

    local-variable-declaration

    expression

    A using statement of the form

    using (ResourceType r1 = e1, r2 = e2, …, rN = eN) statement

    is precisely equivalent to a sequence of nested using statements:

    using (ResourceType r1 = e1)

    using (ResourceType r2 = e2)

    using (ResourceType rN = eN)

    statement

    So we could rewrite our Copy method as follows:

        private static void Copy(string source, string destination)
        {
           
    const int
    BufferSize = 64 * 1024;
           
    using (FileStream input = File
    .OpenRead(source))
           
    using (FileStream output = File
    .OpenWrite(destination))
            {
               
    var buffer = new byte
    [BufferSize];
               
    int
    bytesRead;
               
    while ((bytesRead = input.Read(buffer, 0, BufferSize)) != 0)
                {
                    output.Write(buffer, 0, bytesRead);
                }
            }
        }

    Note however that due to how local-variable-declaration is defined in the language spec, multiple variables have to be of the same type, and you only specify this type once at the beginning of the first declarator.

  • Kirill Osenkov

    Free online function graphing with Silverlight

    • 7 Comments

    I see Jon Skeet has written a function graphing sample using DLR and Silverlight. It occurred to me that it would be very easy to create something like this using my Live Geometry framework.

    So here it is: http://graph.livegeometry.com. One difference is that I didn’t use DLR and Python, but wrote my own hand-written recursive descent parser for math expressions. One reason for this (except the fact that it was overdue for me to write a parser myself) is that I don’t think DLR will run on the Windows Phone 7 (since Expression.Compile() and Reflection.Emit are currently not supported on the phone). Also DLR is a bit on the heavy-side with > 1 MB increase of the .xap file.

    Sources, as usual, at CodePlex.

  • 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...

Page 2 of 7 (164 items) 12345»