For those that followed the Long Path in .NET series that Kim Hamilton wrote a while back, you will be pleased to know that we just released a library over on CodePlex that adds Long Path support to .NET. This project is one of four new experimental projects + source that we released on our new BCL CodePlex site:

BigRational
BigRational builds on the BigInteger introduced in .NET Framework 4 to create an arbitrary-precision rational number class.

Long Path
This library provides functionality to make it easier to work with paths that are longer than the current 259 character limit.

PerfMoniter
PerfMonitor is a command-line tool for profiling the system using Event Tracing for Windows (ETW). PerfMonitor is built on top of the TraceEvent library.

TraceEvent
An experimental library that greatly simplifies reading Event Tracing for Windows (ETW) events.

Expect to see a lot more of these experimental libraries in the future from the BCL. Play around with them and tell us what you think.

Posted by David Kean | 2 comment(s)
Filed under: , ,

The maximum number of static fields allowed in mscorlib?

1020

Yep you read that right, an arbitrary 1020, not even a computer-scientisty power-of-2, like 1024. Static fields are scoped per AppDomain and this limitation is hardcoded in the native implementation of that class. Check out the Rotor source if you are interested (search for STATIC_OBJECT_TABLE_BUCKET_SIZE):

sscli20\sscli20\clr\src\vm\AppDomain.cpp

Have a guess how a colleague of mine, Brian Grunkemeyer, found this out today…

(This limitation is only in mscorlib – other assemblies do not have a limitation, or rather, have an insanely high limit that you should never hit)

Posted by David Kean | 2 comment(s)

Haibo Luo explained way back in 2006 the reasoning behind why Type.FullName and Type.AssemblyQualifiedName return null in certain situations. My reaction was one of surprise when I first encountered this, but it soon made sense once I read the documentation. The workaround, if all you want is a string representation of the type (strictly for display purposes only), is to call Type.ToString().

Recently I’ve been working on a feature for a future version of the Framework which is making use of a lot Reflection, in particular these properties. Unfortunately, I came across a couple of situations where these return null when they really shouldn’t.

The following shows this with an single dimensional array of Action<T>:

Type type = Type.GetType("System.Action`1[]");

Console.WriteLine("Type.FullName: " + (type.FullName ?? "null"));

Which outputs:

Type.FullName: null

Now remember, if you read Haibo’s post above, you would know that Type.FullName returns null when it cannot guarantee that Type.GetType can resolve the same type. Clearly, however, in this situation Type.GetType can round trip the result – as it what was what we used to get the Type in the first place! If you try pointers and references to a generic type definition, such as ‘Action`1*’ and ‘Action`1&’, you’ll notice the same issue.

Okay, so what’s the reason behind this? Well it turns out that the way Reflection decides whether its going to return null or not, is by doing something similar to:

public string FullName
{
    get
    {
        if (!IsGenericTypeDefinition && ContainsGenericParameters)
        {
            return null;
        }

        return GetRealFullName();
    }
}

Now with the above type, an Action<T>[] isn’t actually a generic definition itself, only its element, Action<T>, is. It is however, considered as having unresolved generic parameters, indicated by ContainsGenericParameters (which does walk into elements). Hence why the property takes the the null path.

Now the question that Reflection really should be asking instead of the IsGenericTypeDefinition check, is; ‘am I or any of my elements a generic definition?’, but because generic definitions can’t have element types, can be simply shortened to ‘am I or my root element a generic definition?’ Once, we’ve got the right question, we can now come up with a workaround.

Okay, first we need a way to figure out our root element:

private static Type GetRootElementType(Type type)
{
    Type elementType = type;
    while (elementType.HasElementType)
    {
        elementType = elementType.GetElementType();
    }

    return elementType;
}

Once we can figure out that, the rest is pretty straightforward:

private static string GetFullName(Type type)
{
    string name = type.FullName;
    if (name != null)
        return name;

    // Okay, Reflection's just told us that it can't 
    // uniquely identify this type, let us try
    Type elementType = GetRootElementType(type);
    if (!elementType.IsGenericTypeDefinition)
        return null; // Nope :(

    if (elementType.DeclaringType != null)
    {   // Handle nested classes

        return GetFullName(elementType.DeclaringType) + "+" + type.Name;
    }

    return type.Namespace + "." + type.Name;
}

Note, Type.Name does most of the work for us – it already includes any modifiers such as arrays ([]), pointers (*) and references (&). We also need to make sure that we handle nested types.

Now let’s try the original code again using our new method:

Type type = Type.GetType("System.Action`1[]");

Console.WriteLine("Type.FullName: " + (GetFullName(type) ?? "null"));

Running, outputs:

Type.FullName: System.Action`1[]

Looks good. Now for the ultimate test, the round trip:

Type type1 = Type.GetType("System.Action`1[]");

Type type2 = Type.GetType(GetFullName(type1));

Console.WriteLine("Same type? " + (type1 == type2));

Which in turn outputs:

Same Type? True

Beautiful. And there we have it – a quick any easy way to work around this. Note, although I’ve sent through through a few different types through this, I’ve haven't extensively tested it, so your results may vary. I’ll also leave it up to the reader to come up with a similar fix for Type.AssemblyQualifiedName.

I’ve already pinged the Reflection guys about this, and hopefully we’ll see a fix in a future Framework version.

Posted by David Kean | 4 comment(s)
Filed under: ,

My most favorite improvement in Visual Studio 2010 so far is…accidently mousing over the Toolbox tool window for the first time now only takes 5 seconds before you gain control of Visual Studio, rather than the 30+ seconds it took in Visual Studio 2008.

I heard on the grape vine that they did a bunch of perf work around improving this exact scenario. Now if they could just spend some time on that pesky Add References dialog…

image
Posted by David Kean | 2 comment(s)
Filed under:

As an update to “I can’t believe Microsoft didn’t make [Enter API Name Here] public”, the Visual Studio Languages team (which own the System.Linq namespace as well as the C#, VB and F# compilers) have added a new public version of ExpressionVisitor.

This type allows you to traverse an entire expression graph by simply passing the expression to ExpressionVisitor.Visit(Expression). Each expression type has an associated VisitXXX method (such as VisitMember(MemberExpression), VisitCatchBlock(CatchBlock), etc) that you can override to get called back every time one of these expressions is encountered.

This should make Jeremy and Oren very happy. ;)

Posted by David Kean | with no comments
Filed under: ,

Herman Ventor, the brains behind FxCop's assembly metadata reader, has just released the next version as an open-source project over on CodePlex.

The Common Compiler Infrastructure (CCI) is a set of components for reading and writing CLR assemblies and was developed as an alternative to Reflection. This is an amazing project and if you've ever been frustrated by the limitations of Reflection and Reflection Emit - I would highly recommend downloading and checking it out.

Find out more at: http://ccimetadata.codeplex.com/

Posted by David Kean | 1 comment(s)
Filed under: , ,

I’ve been writing C# code since one of the early betas back in 2001, yet I’ve never run across the following:

error CS1638: 'ToString_WithCache__ShouldReturnICompositionElementDisplayName' is a reserved identifier and cannot be used when ISO language version mode is used.

I was weirded out by this and thought ‘that’s a hell of a coincidence that the C# compiler has an identifier called ‘ToString_WithCache__ShouldReturnICompositionElementDisplayName’, but as it turns out identifiers with two consecutive underscore’s are actually reserved:

Identifiers containing two consecutive underscore characters (U+005F) are reserved for use by the implementation; however, no diagnostic is required if such an identifier is defined. [Note: For example, an implementation might provide extended keywords that begin with two underscores. end note]

You learn something new (however useless) everyday.

(To see this warning you’ll need to turn on ISO-1 in the Language Version drop down in the Advanced build settings)

Posted by David Kean | with no comments
Filed under:

I was reading what was new for Visual Basic 10 over on the VB Futures site, when I came across the following statement:

Overall Visual Basic 10.0 and C# 4.0 will have the closest feature parity at any point in the history of the languages, which will greatly benefit .NET developers who do work in both.

This statement refers to the language changes coming in Visual Studio 2010, such as Visual Basic getting some C#-like features, such as multiline lambdas, auto-implemented properties and implicit line continuation, and C# getting some Visual Basic-like features, such as late binding, implicit pass-by-ref and optional parameters.

I’m disappointment that the language teams feel the need to have what they call ‘co-evolution’, where any new features in one language also get added to the other. Is there any point Microsoft investing in two separate languages, if they do exactly the same thing?

In my opinion (which does not represent Microsoft’s), we would better off adding C-style macros to one of the languages, allowing us to #define the syntax differences between the two languages, and then kill off the other.

What do others think? Should Microsoft continue to support two (what are) basically the same languages, or should they attempt to differentiate them like they have done with F#?

I ran across something interesting on an internal alias about a new marketing campaign on the Visual Studio Team System marketing site that allows you to customize an amusing video that you can send to friends and team members. What caught my eye wasn’t the video itself, but the error that some users were encountering when attempting to view one of the Silverlight-based videos:

Message: Unhandled Error in Silverlight 2 Application [Format_InvalidString]
Arguments:

Debugging resource strings are unavailable. Often the key and arguments provide sufficient information to diagnose the problem. See http://go.microsoft.com/fwlink/?linkid=106663&Version=2.0.31005.0&File=mscorlib.dll&Key=Format_InvalidString   at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
   at System.Number.ParseDouble(String value, NumberStyles options, NumberFormatInfo numfmt)
   at System.Double.Parse(String s, NumberStyles style, NumberFormatInfo info)
   at System.Double.Parse(String s, IFormatProvider provider)
   at System.Convert.ToDouble(String value)
   at PepTalk_Full.DataObjects.doTextOverlay..ctor(XElement element)
   at PepTalk_Full.DataObjects.doPepTalk.Init()
   at PepTalk_Full.DataObjects.doPepTalk..ctor()
   at PepTalk_Full.App.wc_DownloadStringCompleted(Object sender, DownloadStringCompletedEventArgs e)
   at System.Net.WebClient.OnDownloadStringCompleted(DownloadStringCompletedEventArgs e)
   at System.Net.WebClient.DownloadStringOperationCompleted(Object arg)

To keep download sizes smaller, the client Silverlight plug-in does not contain Exception error messages, but by clicking the URL above, or by looking at the stack can you guess what the problem is? I’ll give you a hint – Convert.ToDouble(String) passes CultureInfo.CurrentCulture as the IFormatProvider argument to Double.Parse.

Yep, you guessed it, basically, the application is attempting to parse a string that it has downloaded from the web and the call to Convert.ToDouble is failing because it is expecting the format of the string to match the current culture, while the string itself is formatted using another culture. For example, the string likely contains a value formatted using the invariant culture, say ‘1.00’, but when a visitor from Germany or Norway comes to visit, Convert.ToDouble(String) is looking for a string in the format ‘1,00’.

The irony in all this is that if the Microsoft team or contractor that wrote the Silverlight application were actually using the Code Analysis feature of Team System, they would have received the following warning from Specify IFormatProvider:

Because the behavior of 'Convert.ToDouble(string)' could vary based on the current user's locale settings, replace this call in 'doTextOverlay.doTextOverlay(XElement)' with a call to 'Convert.ToDouble(string, IFormatProvider)'. If the result of 'Convert.ToDouble(string, IFormatProvider)' will be displayed to the user, specify 'CultureInfo.CurrentCulture' as the 'IFormatProvider' parameter. Otherwise, if the result will be stored and accessed by software, such as when it is persisted to disk or to a database, specify 'CultureInfo.InvariantCulture'.

All the developer has to do is to call the overload of Convert.ToDouble that takes an IFormatProvider passing it CultureInfo.InvariantCulture and the application would work on all systems regardless of the user’s culture.

The moral of the story is, use the tools available at your disposal – if you have Team System, use Code Analysis, otherwise, we still offer FxCop as a free download – they both catch bugs like this one.

Posted by David Kean | 2 comment(s)
Filed under: ,

I’m speaking at Code Camp Oz 2009 on April 4th in Wagga Wagga, Australia. I’ll be giving a talk called ‘A lap around the Managed Extensibility Framework’, in which I’ll give a run through of the major features of MEF.

Mitch Denny has also announced the rest of the speakers & sessions, which looks like a great line up this year. I had the pleasure of attending the first one in 2005 when I was last in Australia and it’s not only a great (and free) way to learn more about current and new technologies, but is also a great place to network with peers.

It’s free and run over the weekend of April 4th/5th. Sign up today.

Posted by David Kean | with no comments
Filed under:

One of the things that you might run across when starting to work with MEF, is that by default, all parts are created as singleton (‘shared’) instances.

For example, given the following part:

[Export]
public class MyView
{
}

Running the following code:

TypeCatalog catalog = new TypeCatalog(typeof(MyView));
CompositionContainer container = new CompositionContainer(catalog);

var view1 = container.GetExportedObject<MyView>();
var view2 = container.GetExportedObject<MyView>();

Console.WriteLine("Are same object? " + (view1 == view2));

Outputs:

Are same object? True

In certain scenarios, such as web applications, you typically want the reverse, that is, a new instance (‘non-shared’) of a part created on every request.

We allow you to indicate that, using the CompositionOptionsAttribute:

[Export]
[CompositionOptions(CreationPolicy=CreationPolicy.NonShared)]
public class MyView
{
}

Unfortunately, if you have a lot of them, this can be a bit of a hassle to do this for every part. As luck would have it, the latest drop of MEF allows you modify the default with a little bit of code:

public class TransientCompositionContainer : CompositionContainer
{
    public TransientCompositionContainer(ComposablePartCatalog catalog)
        : base(catalog)
    {
    }

    protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition)
    {
        definition = AdaptDefinition(definition);
        
        return base.GetExportsCore(definition);
    }

    private ImportDefinition AdaptDefinition(ImportDefinition definition)
    {
        ContractBasedImportDefinition namedDefinition = definition as ContractBasedImportDefinition;
        if (namedDefinition != null && namedDefinition.RequiredCreationPolicy == CreationPolicy.Any)
        {   // Only change the creation policy if the importer/requester did not specify one
 
            definition = new ContractBasedImportDefinition(namedDefinition.ContractName,
                                                           namedDefinition.RequiredMetadata,
                                                           namedDefinition.Cardinality,
                                                           namedDefinition.IsRecomposable,
                                                           namedDefinition.IsPrerequisite,
                                                           CreationPolicy.NonShared);
        }

        return definition;
    }
}

Basically what is happening above is that all requests to the container are routed through GetExportsCore. When we see a request (represented as an ImportDefinition) that states that it does not have a preference for a particular creation policy (which is the default when querying from the container, or when using the [Import] attribute), we create a new request that explicitly specifies that it wants a non-shared instance and route that back to the base.

Running the above sample, substituting the standard container with the transient container, should now output:

Are same object? False

There we have it – a container that defaults to non-shared parts. You can download the container below.

Posted by David Kean | 1 comment(s)
Filed under:

We’ve dropped another version of the Managed Extensibility Framework over on our CodePlex site.

Changes since the last drop:

  • Diagnostics improvement. We now provide a lot more information in error messages when something goes wrong with composition. We’ve also made the main types look a lot better under the debugger.
  • Lifetime/Creation Policy. Importers can now request a specific creation policy (ie shared or non-shared) for an injected object if they so want. Non-disposable non-shared objects can now be GC’d before the container is disposed (before it used to hold onto them indefinitely).
  • Ripped AllowNonPublicCompositionAttribute. We now always inject private and internal members.
  • Namespace cleanup. We’ve added a couple of sub namespaces under System.ComponentModel.Composition, called ‘Hosting’ and ‘Primitives’. Hosting contains types commonly used only by host applications, such as ExportProvider, CompositionContainer and the catalogs. Primitives contains types for implementing a custom programming model, such as ComposablePart, ImportDefinition and ExportDefinition.
  • Type name cleanup. Gone are the hideously long type names; AttributedAssemblyPartCatalog, AttributedTypesPartCatalog, AggregratingComposablePartCatalog, and in their place; AssemblyCatalog, TypeCatalog and AggregateCatalog.

Check it out, and tell us what you think.

Posted by David Kean | 4 comment(s)
Filed under: ,

ReflectionTypeLoadException takes the cake with this message:

Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.

This is one of the most frustrating messages to encounter outside of the debugger. What do you think the first thing you are going to do when you hit this in production?….Exactly, look at the LoaderExceptions property, which is impossible without forethought or a debugger.

How could have the loader team improved the usability of this exception ten-fold? By simply outputting the first couple of entries from the property:

Unable to load one or more of the requested types. The first few exceptions are provided below. Retrieve the LoaderException property for more information.
---> Could not load file or assembly ‘Library, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8e9c13fee402ae29' or one of its dependencies. Strong name validation failed.

Much better. Straight away the user can see the root cause of the problem and can react without needing to attach a debugger.

(As a side note, CompositionException in MEF used to suffer from the same problem when I first arrived on the team; luckily, our latest release fixes this)

MMayerl asks over on the MSDN wiki, why we don’t document the undocumented C# keywords __makeref, __reftype, __refvalue and __arglist?

Because that defeats of the purpose of them being undocumented.

They are undocumented for a reason; so that the C# team is free to change and remove these keywords without worrying whether customers have taken dependencies on them. Documenting them conveys an implicit support agreement between Microsoft and the user, thereby preventing the team from ever changing the keywords.

We want less people to use them, not more.

Posted by David Kean | 2 comment(s)
Filed under: ,

I’ve seen recent reports of Visual Studio Code Analysis failing (such as this one) with the following error:

Invalid settings passed to CodeAnalysis task.  See output window for details.

Looking in the output window will show something similar to:

Switch '/targetframeworkversion' is an unknown switch.

As I’ve mentioned earlier, the /targetframeworkversion switch was added in Visual Studio 2008 SP1 to support the new multi-targeting rule. The fact that the FxCop does not understand the switch, is a big indicator that something went astray with the installation of the service pack.

Luckily the fix is rather easy, simple re-install it.

Posted by David Kean | with no comments
Filed under: ,
More Posts Next page »