Jon Skeet's coding blog
- Posts
- 491 from 15 Sep 2005 to 14 Aug 2026
- Posting
- now and then (5 in the last year)
- Kind
- personal blog
- Feed
- https://codeblog.jonskeet.uk/feed/
2026 4
2025 11
- Changing Immutable Collections
- Records and the ‘with’ operator, redux
- Unexpected inconsistency in records
- Election 2029: Postcodes
- Records and Collections
- Election 2029: Storage
- Election 2029: Data Models
- Election 2029: Technical overview
- Election 2029: Introduction
- Election 2029: The Impossible Exception – Solved
- Election 2029: An Impossible Exception
2024 7
2023 3
2022 8
2021 4
2020 8
2019 11
- Reducing my international speaking
- V-Drum Explorer: MIDI interface
- V-Drum Explorer: Introduction
- Options for .NET’s versioning issues
- Why I don’t start versions at 0.x any more
- Using “git bash” from AppVeyor
- Versioning limitations in .NET
- Lying to the compiler
- Storing UTC is not a silver bullet
- Hosting ASP.NET Core behind https in Google Kubernetes Engine
- NullableAttribute and C# 8
2018 5
2017 13
- NuGet package statistics
- Diagnosing a Linux-only unit test failure
- Diagnosing a VS-only build problem
- Diagnosing a corner-case tooling bug
- Diagnosing a single slow test
- Diagnosing slow tests (again)
- Diagnostics everywhere!
- Using .NET Core 2.0 SDK on Travis
- Upcoming speaking engagements
- Imposter Syndrome (part 2)
- Imposter syndrome (part 1)
- Surprise! Creating an instance of an open generic type
- All about java.util.Date
2016 6
2015 7
2014 19
- C# 6 in action
- When is an identifier not an identifier? (Attack of the Mongolian Vowel Separator)
- When is a string not a string?
- Writing and speaking update
- Violating the “smart enum” pattern in C#
- The mysteries of BCL time zone data
- When is a constant not a constant? When it’s a decimal…
- The BobbyTables culture
- Object pooling and thread safety
- New blog hosting
- Micro-optimization: the surprising inefficiency of readonly fields
- Anti-pattern: parallel collections
- Diagnosing Portable Class Libraries
- Extension methods, explicitly implemented interfaces and collection initializers
- Quick brainteaser
- C# 6: First reactions
- How many 32-bit types might we want?
- Diagnosing issues with reversible data transformations
- A tale of two puzzles
2013 9
- Career and skills advice
- Casting vs “as” – embracing exceptions
- Array covariance: not just ugly, but slow too
- But what does it all mean?
- Book Review: Async in C# 5.0
- New tool to play with: SemanticMerge
- The Open-Closed Principle, in review
- C# in Depth 3rd edition available for early access, plus a discount code…
- Fun with Object and Collection Initializers
2012 17
- Stack Overflow question checklist
- Noda Time v1.0 released
- How can I enumerate thee? Let me count the ways…
- Stack Overflow and personal emails
- The future of “C# in Depth”
- The perils of conditional mutability
- More fun with DateTime
- Type initializer circular dependencies
- Diagnosing weird problems – a Stack Overflow case study
- Eduasync 20: Changes between the VS11 Preview and the Visual Studio 11 Beta
- Subtleties in API design – member placement
- Currying vs partial function application
- Eduasync part 19: ordering by completion, ahead of time…
- Coding in the style of Glee
- CodeMash 2012 report
- Eduasync part 18: Changes between the Async CTP and the Visual Studio 11 Preview
- Awaiting CodeMash 2012
2011 57
- Book Review: Fluent C# (Rebecca Riordan, Sams)
- Eduasync part 17: unit testing
- Eduasync part 16: Example of composition: majority voting
- Eduasync part 15: implementing COMEFROM with a horrible hack
- Laptop review: Kobalt G150
- Upcoming speaking engagements
- Optimization and generics, part 2: lambda expressions and reference types
- Optimization and generics, part 1: the new() constraint (updated: now with CLR v2 results)
- Speaking engagement: Progressive .NET, London, September 7th
- Eduasync part 14: Data passing in coroutines
- Eduasync part 13: first look at coroutines with async
- Eduasync part 12: Observing all exceptions
- Eduasync part 11: More sophisticated (but lossy) exception handling
- LINQ To Objects and the performance of nested “Where” calls
- Eduasync part 10: CTP bug – don’t combine multiple awaits in one statement…
- Eduasync part 9: generated code for multiple awaits
- Eduasync part 8: generated code from a complex async method
- Eduasync part 7: generated code from a simple async method
- Eduasync part 6: using the infrastructure manually
- Eduasync part 5: making Task awaitable
- Eduasync part 4: Filling in AsyncTaskMethodBuilder
- Eduasync part 3: the shape of the async method / awaitable boundary
- Eduasync part 2: the shape of the caller / async method boundary
- Eduasync part 1: introduction
- Of memory and strings
- Edulinq – the e-book
- Reimplementing LINQ to Objects: Part 45 – Conclusion and List of Posts
- Reimplementing LINQ to Objects: Part 44 – Aspects of Design
- Reimplementing LINQ to Objects: Part 43 – Out-of-process queries with IQueryable
- C# in Depth 2nd edition: now available in mobi/epub (Kindle) format
- Reimplementing LINQ to Objects: Part 42 – More optimization
- Reimplementing LINQ to Objects: Part 41 – How query expressions work
- Reimplementing LINQ to Objects: Part 40 – Optimization
- Reimplementing LINQ to Objects: Part 39 – Comparing implementations
- Reimplementing LINQ to Objects: Part 38 – What’s missing?
- Reimplementing LINQ to Objects: Part 37 – Guiding principles
- Gotcha around iterator blocks
- Reimplementing LINQ to Objects: Part 36 – AsEnumerable
- Reimplementing LINQ to Objects: Part 35 – Zip
- Reimplementing LINQ to Objects: Part 34 – SequenceEqual
- Reimplementing LINQ to Objects: Part 33 – Cast and OfType
- Reimplementing LINQ to Objects: Part 32 – Contains
- Reimplementing LINQ to Objects: Part 31 – ElementAt / ElementAtOrDefault
- Reimplementing LINQ to Objects: Part 30 – Average
- Reimplementing LINQ to Objects: Part 29 – Min/Max
- Reimplementing LINQ to Objects: Part 28 – Sum
- Reimplementing LINQ to Objects: Part 27 – Reverse
- Reimplementing LINQ to Objects: Part 26d – Fixing the key selectors, and yielding early
- Reimplementing LINQ to Objects: Part 26c – Optimizing OrderedEnumerable
- Reimplementing LINQ to Objects: Part 26b – OrderBy{,Descending}/ThenBy{,Descending}
- Reimplementing LINQ to Objects: Part 26a – IOrderedEnumerable
- Reimplementing LINQ to Objects: Part 25 – ToDictionary
- Reimplementing LINQ to Objects: Part 24 – ToArray
- Reimplementing LINQ to Objects: Part 23 – Take/Skip/TakeWhile/SkipWhile
- Reimplementing LINQ to Objects: Part 22 – GroupJoin
- Reimplementing LINQ to Objects: Part 21 – GroupBy
- Reimplementing LINQ to Objects: Part 20 – ToList
2010 65
- Reimplementing LINQ to Objects: Part 19 – Join
- Reimplementing LINQ to Objects: Part 18 – ToLookup
- Reimplementing LINQ to Objects: Part 17 – Except
- Reimplementing LINQ to Objects: Part 16 – Intersect (and build fiddling)
- Reimplementing LINQ to Objects: Part 15 – Union
- Reimplementing LINQ to Objects: Part 14 – Distinct
- Reimplementing LINQ to Objects: Part 13 – Aggregate
- Reimplementing LINQ to Objects: Part 12 – DefaultIfEmpty
- Reimplementing LINQ to Objects: Part 11 – First/Single/Last and the …OrDefault versions
- Reimplementing LINQ to Objects: Part 10 – Any and All
- Reimplementing LINQ to Objects: Part 9 – SelectMany
- Reimplementing LINQ to Objects: Part 8 – Concat
- Reimplementing LINQ to Objects: Part 7 – Count and LongCount
- Reimplementing LINQ to Objects: Part 6 – Repeat
- Reimplementing LINQ to Objects: Part 5 – Empty
- Reimplementing LINQ to Objects: Part 4 – Range
- Reimplementing LINQ to Objects: Part 3 – “Select” (and a rename…)
- A Model/View to a Kill (Naked came the null delegate, part 5)
- Creative freedom, control, and the balance of power
- The joys of date/time arithmetic
- The importance of context, and a question of explicitness
- Multiple exceptions yet again… this time with a resolution
- Using extension method resolution rules to decorate awaiters
- Propagating multiple async exceptions (or not)
- Configuring waiting
- Evil code – overload resolution workaround
- Dreaming of multiple tasks again… with occasional exceptions
- C# in Depth 2nd edition: ebook available, but soon to be updated
- Control flow redux: exceptions in asynchronous code
- Dreaming of multiple tasks
- C# 5 async: experimenting with member resolution (GetAwaiter, BeginAwait, EndAwait)
- C# 5 async: investigating control flow
- C# 5 async and choosing terminology: why I’m against “yield”
- Initial thoughts on C# 5’s async support
- Overloading and generic constraints
- The curious case of the publicity-seeking interface and the shy abstract class
- Book Review: Effective C# (2nd edition) by Bill Wagner
- Non-iterable collection initializers
- You are all individuals! (I’m not…)
- Reply to a reply… tweaking refactoring
- Query expression syntax: continuations
- Mini-post: abstractions vs repetition; a driving analogy
- Very quick interlude: I know that CAPTCHAs aren’t working on this blog if you’re using Chrome
- Reimplementing LINQ to Objects: Part 2 – “Where”
- Reimplementing LINQ to Objects: Part 1 – Introduction
- Presentation preparation
- Don’t let this get away
- Code and data
- Writing the perfect question
- Reflecting on presentation skills: The Guathon, August 13th 2010
- There’s a hole in my abstraction, dear Liza, dear Liza
- Iterate, damn you!
- Degrees of reality in sample code
- How many Jedi?
- Epicenter 2010: quick plug and concessionary tickets
- How do we raise our game?
- Book review: “Confessions of a public speaker” by Scott Berkun
- Documentation with Sandcastle – a notebook
- Just how lazy are you?
- Speaking of which…
- Optimisations in LINQ to Objects
- The irritation of bad names
- Type initialization changes in .NET 4.0
- LINQ to Rx: second impressions
- First encounters with Reactive Extensions
2009 51
- “Magic” null argument testing
- Custom value types are like buses
- Where do you benefit from dynamic typing?
- Just how spiky is your traffic?
- Noda Time gets its own blog
- Noda Time is born
- What’s in a name (again)?
- Revisiting randomness
- OMG Ponies!!! (Aka Humanity: Epic Fail)
- Contract classes and nested types within interfaces
- MVP Again
- Migrating from Visual Studio 2010 beta 1 to beta 2 – solution file change required
- Iterating atomically
- Generic collections – relegate to an appendix?
- MVP no more
- An object lesson in blogging and accuracy; was: Efficient “vote counting” with LINQ to Objects – and the value of nothing
- API design: choosing between non-ideal options
- Generic constraints for enums and delegates
- Recent activities
- The “dream book” for C# and .NET
- Tricky decisions… Code Contracts and Parallel Extensions in C# in Depth 2nd edition
- Evil Code of the Day: variance and overloading
- Non-review: The Data Access Handbook by John Goodson and Robert A. Steward
- Faking COM to fool the C# compiler
- Books going cheap
- Evil code of the day
- OS Jam at Google London: C# 4 and the DLR
- Dynamic type inference and surprising possibilities
- Reasons for voting on questions and answers
- A different approach to inappropriate defaults
- Language proliferation
- RFC: C# in Depth 2nd edition, proposed changes and additions
- Go on, ask me anything
- Buffering vs streaming benchmark: first results
- Benchmarking IO: buffering vs streaming
- Breaking Liskov
- Book Review: C# 2008 and 2005 Threaded Programming: Beginner’s Guide
- Current book project: Real World Functional Programming
- What’s in a name?
- Answering technical questions helpfully
- Benchmarking: designing an API with unusual goals
- For vs Foreach on arrays and lists
- Programming is hard
- Benchmarking made easy
- RFID: What I really want it for
- Designing LINQ operators
- Quick rant: why isn’t there an Exception(string, params object[]) constructor?
- Stack Overflow reputation and being a micro-celebrity
- Stack Overflow Reputation Tool now online
- Horrible grotty hack: returning an anonymous type instance
- You don’t have to use query expressions to use LINQ
2008 96
- New version of Data Structures and Algorithms book now online
- Value types and parameterless constructors
- Redesigning System.Object/java.lang.Object
- List of talks now up on C# in Depth site
- The Snippy Reflector add-in
- Copenhagen C# talk videos now up
- November 19th: London .NET User Group, Push LINQ!
- How much do you care about blog tags?
- Jaffa bugs
- .NET 4.0’s game-changing feature? Maybe contracts…
- Returning from Copenhagen
- C# 4.0: dynamic ?
- What other Enumerable extension methods would you like to see?
- DeveloperDeveloperDeveloper: Registration now open (hurry!)
- Mapping from a type to an instance of that type
- Why boxing doesn’t keep me awake at nights
- DotNetRocks interview
- Non-nullable reference types
- Formatting strings
- Copenhagen talk on C# – what do you want to hear about?
- New addiction: Stack Overflow
- Book Review: Programming C# 3.0 by Jesse Liberty and Donald Xie
- Book review: Pro LINQ – Language Integrated Query in C# 2008, by Joe Rattz
- Book reviews – what do you look for?
- Logging enumeration flow
- Annoying IE8 beta 2 CSS breakage
- With apologies to Flanders and Swann
- Developer Developer Developer day 7: voting now open
- Data Structures and Algorithms: new free eBook available (first draft)
- Core .NET refcard now available
- Lessons learned from Protocol Buffers, part 4: static interfaces
- Lessons learned from Protocol Buffers, part 3: generic type relationships
- Holiday blogging
- Lessons learned from Protocol Buffers, part 2: self-referential generic types
- Lessons learned from Protocol Buffers, part 1: messages, builders and immutability
- Pre-Copenhagen interview
- Speaking in Copenhagen, October 30th
- Visual Studio 2008 SP1 and .NET 3.5 SP1 both out now
- C# refcard now available (free) from DZone
- Thank you, JetBrains: dotTrace rocks
- Making reflection fly and exploring delegates
- Making the most of generic type inference
- Book review: Accelerated C# 2008 by Trey Nash
- Calling Trey Nash…
- Judging a book by its cover (or title)
- Google release protocol buffers as an open source project
- The trouble with book reviews
- Manning book draw
- Blog update
- Automatic lambda expressions
- I’m Sorry, I Haven’t a Cluestick
- Guest post: Joe Albahari reviews C# in Depth
- Parallel Extensions June CTP
- More parallelisation fun: Conway’s Game of Life
- Mandelbrot revisited – benchmark edition
- The Beauty of Closures
- C# in Depth – it’s really real
- Programming “in” a language vs programming “into” a language
- Book review: User Interface Design for Programmers (Joel Spolsky)
- Critical dead-weight
- Google, here I come!
- We’ve shipped! C# in Depth is out now (ebook)
- Book review: C# 3.0 in a Nutshell
- Range variables – is it just me that thinks they’re different?
- PostSharp and iterator blocks – a beautiful combination
- Book review: Head First C#
- Book review/preview: “C# Query Expressions And Supporting Features in C# 3.0” (Eckel/King)
- C# 4: Immutable type initialization
- Reviewing other C# books?
- Reading Geek Night 2 – March 28th
- C# 4, part 5: Other bits and bobs which probably don’t merit inclusion
- The value of a language specification
- C# 4 idea: Iterator blocks and parameter checking
- Trivia: when is a no-op not a no-op?
- Odd query expressions
- Implementing deferred execution, and a potential trap to avoid
- Data pipelines as a conceptual stepping stone to higher order functions
- Visualising the Mandelbrot set with LINQ – yet again
- LambdaExpression – source code would be nice
- Visual LINQ: Watch query expressions as they happen!
- My first screencast – automatic properties
- Human LINQ
- Language design, when is a language “done”, and why does it matter?
- C# 4, part 4: My manifesto and wishlist
- Macros, and languages within languages
- C# 4, part 3: Ideas from Microsoft
- C# 4, part 2: Ideas from other community members
- A simple extension method, but a beautiful one
- C# 4, part 1: Looking back at the past
- Immutability and inheritance
- Bridging gaps, and finding my role
- Types of Parallelism
- Extension methods on lamdba expressions don’t work, unfortunately
- LINQ to Objects – not just for in-memory collections
- “Push” LINQ revisited – next attempt at an explanation
- Last post about the book (nearly) and a new source of information…
2007 46
- Boxing day
- C# in Depth: All chapters available in MEAP!
- Covariance and void return types
- Refactris
- A cautionary parallel tale: ordering isn’t simple
- Group pipelining returns: new and improved design
- Don’t call us, we’ll call you – push enumerators
- VS2005 and VS2008 co-existence
- Visual Studio 2008 is out now!
- C# in Depth: Chapters 8 and 9 now in MEAP
- Getting started with F#
- Joe Duffy speaks as well as he writes
- I love LINQ: Simplifying a tedious task
- Book news
- C# in Depth: Chapters 6 and 7 now in MEAP
- Fun with captured variables
- LINQ to Silliness: Generating a Mandelbrot with parallel potential
- Yeehaa! Framework source code, here we come!
- C# in Depth: Chapters 4 and 5 now available in MEAP
- Announcement: Partnership with Iterative Training
- Java isn’t an acronym
- Announcing “C# in Depth”
- How does everyone else mock web services?
- Writing user interfaces
- Extension methods and .NET 2.0
- Is C# 3 too big to learn from scratch?
- Smart enumerations
- Visual Studio 2008 (Orcas) Beta 2 Released
- Overloading == to return a non-boolean
- Who do the “stars” look up to?
- Why hasn’t Microsoft bought JetBrains yet?
- Implementing Ruby on .NET, and the importance of specifications
- Writing is hard work: what I’ve been up to recently…
- Non-volatile reads and Interlocked, and how they interact
- The CCR (Concurrency and Coordination Runtime) is out – apparently!
- Sheer Evil: Rethrowing exceptions in Java
- Visual Studio 2005 vs Eclipse – again, but this time with ReSharper…
- Wacky Ideas 3: Object life-cycle support
- Wacky Ideas 2: Class interfaces
- Wacky Ideas 1: Inheritance is dead, long live mix-ins!
- Wacky Ideas – Introduction
- What would make a good Java book?
- Build and config friendliness counts
- New blog, new project
- Wii and MythTV: The future of my living room?
- Groovy 1.0 released
2006 23
- Everything old is new again
- The CLI memory model, and specific specifications
- Unit tests rock, I suck, news at 11
- Why development is still hard in 2006
- Opening up the .NET framework source code
- An alternative CV strategy
- Elegant comparisons with the null coalescing operator
- Broken windows and unit testing
- The 7 Deadly Sins of Software Development
- Father of Three
- PowerShell in Action
- Groovy
- Faith blog
- MSDN Product Feedback Center – use it!
- Vista and External Memory Devices
- Inheritance Tax
- Worst product names ever?
- Bringing Subversion and Fitnesse together
- List.ForEach vs foreach(…)
- Singletons and inheritance
- ICloneable? Not quite…
- Nice doc comment idea
- Enhanced enums in C#
2005 21
- Deadlock detection – finally released
- Pedantry – how much is too much?
- What kind of deadlock prevention do you want?
- Visual Studio vs Eclipse
- RSS for my articles
- New (to me) threading paradigms
- System.Random (and java.util.Random)
- Adverts on my C# article pages?
- Code formatter online
- CLI spec mistake with unboxing and enums
- CSS in the blog
- Book idea
- Yay! I’m not the only one who doesn’t like designers…
- Corner cases in Java and C#
- A short case study in LINQ efficiency
- Problems posting comments?
- Nasty generics restrictions
- Improvement to extension method syntax
- LINQ, DLinq, XLinq and C# 3.0
- Overuse of regular expressions
- Welcome!