Phillip Trelford's Array

POKE 36879,255

MSDNify Types

Following on from yesterday’s post on Disinherited Types where I implement an F# type provider that hides inherited members of a type to let you focus on the useful members. The example was the WPF Button control which contains around 300 members via 9 levels of inheritance and appears to flout the object-oriented principle of composition over inheritance.

Microsoft’s MSDN documentation takes another approach to the problem of making relevant members discoverable by grouping members by type, i.e. all properties, all methods, all fields and all events:

Button class docs

MSDNify Type Provider

To give the same discoverable experience in the editor I’ve created the MSDNify Type Provider that groups members by type:

Button by member type

From the filtered member type groups you can select the member you are interested in:

Button events

This in effect mirrors the MSDN docs making it easier to find the useful members.

Source Code

The implementation is very similar to the Disinherited Type Provider discussed in yesterday’s post.

The code is available on GitHub: https://github.com/ptrelford/MSDNify

Disinherited Types

One of the things that’s always bugged me when using Windows UI libraries like WinForms and WPF is the sheer number of members that pop up in intellisense for a control. The Button type in WPF has around 300 members and a total of 9 levels of inheritance making it hard to find the useful members. Or to put it another way the inherited members occlude the useful members:

Button members

The picture above shows what you actually see in the code completion box in the editor, however for a button you’re probably more interested in the Click event, but that’s several pages away.

Disinherit Type Provider

As a thought experiment I’ve implemented an F# Type Provider that hides type members after a specified level of inheritance:

Disinherited button

In the picture above the members now almost fit in a single page. The last property, not visible here, is an extra property added by the type provider that provides all the hidden members for the instance:

Button instance

 

Type Provider Implementation

Underneath the covers the type provider takes an assembly name as a static parameter and optionally the level of inheritance to expose.

[<Literal>]
let name = @"PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
type WPF = Disinherited< name , level=1 >
let button = WPF.Button()

The provider then reflects over the types in the assembly and creates a proxy type as a provided type and exposes members that are declared within the specified inheritance level.

To provide the member we simply create a corresponding provided member with an expression that evaluates to the underlying type’s member:

    let addMember (def:ProvidedTypeDefinition) ty (mem:MemberInfo) =
        match mem.MemberType with
        | MemberTypes.Constructor ->
            let ci = mem :?> ConstructorInfo
            let c = ProvidedConstructor(toParams ci)
            c.InvokeCode <- fun args -> Expr.Coerce(Expr.NewObject(ci,args), typeof<obj>)
            def.AddMember(c)
        | MemberTypes.Field ->
            let fi = mem :?> FieldInfo
            let field = ProvidedField(mem.Name, fi.FieldType)
            def.AddMember(field)
        | MemberTypes.Property ->
            let pi = mem :?> PropertyInfo
            let prop = ProvidedProperty(mem.Name, pi.PropertyType) 
            prop.GetterCode <- fun args -> Expr.PropertyGet(Expr.Coerce(args.[0],ty), pi)
            def.AddMember(prop)
        | MemberTypes.Event ->
            let ei = mem :?> EventInfo
            let ev = ProvidedEvent(mem.Name, ei.EventHandlerType) 
            ev.AdderCode <- fun args -> Expr.Call(Expr.Coerce(args.Head,ty),ei.GetAddMethod(), args.Tail)
            ev.RemoverCode <- fun args -> Expr.Call(Expr.Coerce(args.Head,ty), ei.GetRemoveMethod(), args.Tail)
            def.AddMember(ev)
        | MemberTypes.Method ->
            let mi = mem :?> MethodInfo
            if not mi.IsSpecialName then
                let m = ProvidedMethod(mi.Name, toParams mi, mi.ReturnType)
                m.InvokeCode <- fun args -> Expr.Call(Expr.Coerce(args.Head,ty), mi, args.Tail)
                def.AddMember(m)
        | _ -> ()

The entire provider is implemented in around 100 lines of code, I’d be interested to hear if anybody else finds it useful :)

Source code

The source is available on GitHub: https://github.com/ptrelford/Disinherit

Has C# Peaked?

Microsoft’s C# programming language first appeared in 2000, over 15 years ago, that’s a long time in tech.

Every month or so there’s a “Leaving .Net” articles, the last one I bumped into was “The collapse of the .net ecosystem” from Justin Angel:


The article shows, through a series of charts, the level of interest in C# peaking and then falling.

This is what I’d consider to be the natural continuum of things, where languages have their day, and then slowly decline. In the past C was my primary language, then C++ and so on, why should C# be any different?

Disclaimer: This is not a leaving .Net post, just some of my own research that I thought I’d share, with a focus on the UK as that’s where I live.

Job trends

Indeed.com provides statistics on job placements with specific keywords, lets look at C#:

csharp jobgraph

This chart appears to show job adverts peaking between around 2010 and 2012 and tapering off fairly heavily after that.

Google trends

Google trends lets you track interest over time based on a keyword, here I'm looking at C# in the UK:


On this chart the peak seems to be earlier, around 2009, perhaps the trend can be seen earlier in the UK, but again the decline in interest is clearly visible.

TIOBE

Questions around the validity of TIOBE’s numbers abound, but here it is anyway:

TIOBE Index for CSharp

Here the peak appears to be around 2012, although the drop is perhaps less pronounced.

PYPL

Yet another popularity index this time tracking google trends for “C# tutorial” in the UK:

PYPL CSharp UK

This chart shows uses a logarithmic scale, however what we might surmise, if the numbers are to believed, is that interest in C# appears to fall off a cliff towards the end of 2014.

Stack Overflow

The recent stackoverflow developer survey also shows a significant decline in interest from 44.7% in 2013 to 31.6% in 2015. Developer’s current preferences are also quite revealing:

image

 

Where’s everyone gone?

This is only conjecture, but from my experience of .Net oriented developer events over the years in the UK, C# has always had a significant focus on the web and ASP.Net. My suspicion is that with the rise of thick-client JavaScript and mobile, significant numbers of developers have been migrating naturally towards those ecosystems.

Should I panic?

Probably not, there’s still plenty of C# jobs out there for now, and hell, some of the best paid jobs nowadays are for maintaining C++ and even COBOL systems. But if the numbers are anything to go by then we can say that C# interest has peaked.

That said who knows what the future will hold and perhaps like C++ there’ll be a renaissance in the future, although C++’s renaissance never really brought it back to the levels of it’s heady hey days.

Then again perhaps it’s more pragmatic not to dwell too heavily on the past, accept the numbers, and look to a new future. If you’re skills extend beyond one language then I guess you’ve probably got nothing to worry about, otherwise perhaps it’s time to pick up a new language and new paradigms.

And I’ll leave you with a question: Do you think you’ll be using the same programming language in 5 years time?