1/ An interesting bit of history for .NET and C# is that there used to be a public System.Variant type. It was actually a keyword in C# for a while, alongside of object. If you’re unfamiliar with variants, they are a tagged union type.
2/ This means that they can represent many different data types and contain a ‘tag’ (a small enumeration) that defines the type of data they hold. This evolved because COM uses variants heavily, as did VB6 (and many other languages).
3/ In the original iterations of VB.NET, Variant was used for any untyped declaration (e.g. Dim a, b). Variants and System.Object are similar in some ways, and as you might guess, this led to problems.
4/ Variants were implemented as value-types in .NET. This meant that given a variant there were two ways to ‘get’ an object. You could box the variant itself, or you could get the object representation of the *contents* of the variant.
5/ The second is far and away the more common operation, though once you start storing variants into lists (like ArrayList), it starts to get confusing. An example where this kind of confusion came up in C# is this scenario:
6/ Is that a delegate onto variant’s GetHashCode or MyClass instance’s GetHashCode? We did define rules for these cases, but it added complexity that felt onerous. The concept of ‘null’ is also somewhat confusing with variants.
7/ Variants can represent ‘missing’, ‘null’, ‘empty’, (and in VB6 also Nothing). This is somewhat like the confusion that undefined and null creates in JavaScript, but worse. Outside of the confusion for the language, the complexity in the framework was arguably worse.
8/ There were many overloads in the framework that ended up taking both object and variant. It also made cross language compatibility between C#, VB.NET, and other languages much more difficult. For C#, we removed variant as a keyword and simple-type.
9/ More globally, we decided to centralize on object to better unify the type system, improve cross language compatibility, and reduce complexity. This had big implications for VB6 compatibility and COM interoperability that I’ll save for another thread.
10/ This particular decision was difficult and contentious. As mentioned, it had implications for existing language compat and interop, two value propositions for .NET. In hindsight, I believe it was the right call – but .NET would look entirely different if we had either chosen
11/ to unify on variant and/or keep both.

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with Anson Horton

Anson Horton Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @AnsonHorton

28 Dec
1/ I haven't mentioned much about C# integration into Visual Studio yet, but at the same time we were working on creating a new language, a new runtime, and a new framework we also decided to take disparate shells (MSDEV, devenv, VB6) and combine them. This was… a lot.
2/ As you might expect, taking on so much at the same time meant a very long development cycle. For those folks using VS6 it was a long wait for VS7 (‘98 to ’02). Regardless, we wanted to continue to provide a compelling LOB (line of business) client app framework while also
3/ enabling web apps (via ASP.NET, web forms/services, etc.). The client app framework manifested as Windows Forms and was the next iteration of a RAD app creation environment. The Windows Forms designer is extremely rich and intended to make developing UI-rich
Read 15 tweets
26 Dec
1/ The C# development team, for V1, consisted of 5 individual engineers, a lead, and a couple of PMs. 4 of the engineers worked on implementing the compiler, and the last engineer worked on the Visual Studio integration (e.g., IntelliSense).
2/ The C# compiler was written entirely in C++ as was much of Visual Studio at the time. Everyone on the team wanted to implement the compiler in C#, but as I mentioned previously, expediency was key and when we started, we needed to bootstrap. That was done in C++, so it stuck.
3/ The compiler was largely implemented as a batch compiler. We had a no-release heap, which was extremely efficient for straight-through compilation and totally useless for interactive scenarios. Therefore, the compiler and what we call the language service were implemented
Read 11 tweets
25 Dec
1/ It's probably not the first thing you think of, but when we started .NET (COM+) in the late 90s, C# didn't exist yet. We were working on it at the same time as the CLR and the framework. So, you might wonder, what language was being used to generate IL and write the BCL?
2/ The answer is a language that we called SMC that Peter Kukol wrote the compiler for. Peter is a flat out amazing engineer and wrote the core parts of the compiler in just a few days. This unblocked the framework team, allowed vetting the runtime and interpreter, etc.
3/ SMC was a trimmed down C++ variant and the compiler was written in itself (i.e. SMC). It didn't support things like destructors, multiple inheritance, virtual base classes, etc. But, overall it enabled progress that would have otherwise been stalled.
Read 10 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal Become our Patreon

Thank you for your support!

Follow Us on Twitter!