Since the early days of C# 9, I’ve been doing writeups on all of the new features including init-only properties, record types, top level programs and more. And ever since those writeups, I’ve had people say “Yeah, I get I can read that, but can you just give me the gist of how to use the feature?”. I thought that a single page writeup would be short enough but I do get that it’s sometimes easier to explain in a 1 minute video. And so that’s what I’ve done!

I’ve created a completely free C# 9 video course that walks you through all of the features at a high level, to get you up and running as soon as possible. There’s no waffle. There’s no me writing screeds of code on video while you wait for me to get to the point. They are all one take wonders of me doing my best explanation of every C# 9 feature I can think of. And best of all, you can watch the entire series on your lunch break and come back in the afternoon ready to put C# 9 into action.

Interested? Grab the videos here for free!




Watch Now

If you are more of a text person, again, all of the information is available in posts below  :

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

So anyone who uses Entity Framework/EF Core knows that you can run migrations from powershell/package manager console like so :

Update-Database

And you probably also know that with EF Core, you can also use the dotnet ef command like so :

dotnet ef database update

But in rare cases, you may have a need to run migrations on demand from your C#/.NET Core code, possibly by calling an API endpoint or from an admin screen. This was generally more of an issue in older versions of Entity Framework that had real issues with the “version” of the database versus the “version” that the EF Code thought it should be. Infact, put simply, it would bomb out.

In EF Core, this is less of an issue as your code won’t die until it actually tries to do something that it can’t complete (e.g. Select a column that doesn’t exist yet). But there are still some cases where you want to deploy code, test it works in a staging environment against the live database, *then* run database migrations on demand.

Migrating EF Core Database From C#

It’s actually very simple.

var migrator = _context.Database.GetService<IMigrator>();
await migrator.MigrateAsync();

Where _context is simply your database context. That’s it! Crazy crazy simple!

Checking Pending Migrations

It can also be extremely handy checking which migrations need to be run before attempting to run them. Even then, it can be useful to know which state the database is in from an admin panel or similar just to diagnose production issues. For example, if you roll a manual process of updating the production database, it can be useful to see if it’s actually up to date.

await _context.Database.GetPendingMigrationsAsync()

Really simple stuff.

Migrating EF Core On App Startup

In some cases, you really don’t care when migrations are run, you just want them to migrate the database when the app starts. This is good for projects that the timing of the database migration really doesn’t matter or is an incredibly small rollout window. For example, a single machine of a low use web app probably doesn’t need all the bells and whistles for a separate database rollout, it just needs to be on the latest version at any given time.

For that, .NET Core has this new paradigm of a “StartupFilter”. The code looks like so :

public class MigrationStartupFilter<TContext> : IStartupFilter where TContext : DbContext
{
    public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
    {
        return app =>
        {
            using (var scope = app.ApplicationServices.CreateScope())
            {
                foreach (var context in scope.ServiceProvider.GetServices<TContext>())
                {
                    context.Database.SetCommandTimeout(160);
                    context.Database.Migrate();
                }
            }
            next(app);
        };
    }
}

Startup Filters in .NET Core are basically like Filters in MVC. They intercept the startup process and do “something” before the application starts, and only on startup. I actually haven’t made much use of them in the past but recently I’ve found them to be incredibly handy. If you ever made use of the global.asax startup methods in Full Framework .NET, then this is pretty similar.

We can then add our this filter to our startup pipeline by editing our startup.cs file like so :

services.AddTransient<IStartupFilter, MigrationStartupFilter<Context>>();

Where Context is our database context. Again, super simple stuff but something that you’ll probably end up using in every new project from now on!

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

Getting Setup With C# 9

If you aren’t sure you are using C# 9 and/or you want to start using some of the new shiny features in the C# language, be sure to read our quick guide on getting setup with C# 9 and .NET 5. Any feature written about here is available in the latest C# 9 preview and is not a “theoretical” feature, it’s ready to go!

C# 9 Features

We are slowly working our way through all new C# 9 features, if you are interested in other new additions to the language, check out some of the posts below.

Free C# 9 Video Course

Are you one of those people that sees a big wall of text on a programming blog and instantly tunes out? Well you aren’t alone! In fact, I got hassled so much with people asking me “Can’t you just quickly share your screen and show me?” rather than reading a blog post, I decided I may as well quickly record the need to know bits of C# 9. So that’s what I’ve done!

My “What’s New In C# 9” course is completely free and will get you up and using C# 9 features in less than an hour (seriously!). Did I mention it’s FREE?

Watch For Free Now!

Init-Only Properties In C# 9

Before we go much further, I highly recommend reading our guide on Init-Only Properties in C# 9 here. Record types in C# 9 are borderline an extension of the level of immutability that init-only properties give, and so much of this article will refer back to that.

Record Types Crash Course

The gist of a record type is that it provides an easier way to use the immutability features within C# 9 (init) and provides better equality comparisons…. Or that’s the theory anyway.  I will say that everything within this guide is working right now in the latest SDK. I’ve read a bunch of tutorials that are simply wrong or don’t work.(mini rant) It happens every single C# release where people want to be the first to do a writeup about something that they do guides with “pesudocode”.

I think as well it’s more frustrating than ever with Records because everyone is just copy and pasting the happy path given out in the .NET Core announcements. Rather than actually playing with the code and seeing what it actually does, and where it’s short comings are.

Anyway. Back to records! If we look at a simple record definition like so :

public record Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

Now if you wrote code like so, you might expect it to throw an exception (Because everyone is talking about how records are immutable!)  :

var person = new Person();
person.Name = "John Smith";//No Exception

But it doesn’t.

We’ll soon find out how to make it throw an error but it’s a little confusing when you first start using Records because everyone has talked about immutability and how records solve that problem when in reality, they only solve it in very specific scenarios. Depending on which documentation you read, it can be very confusing.

I found a good Github Issue against the dotnet docs here : https://github.com/dotnet/docs/issues/20601 that goes into some of the confusing wording. I think that the idea is that Records *help* you write immutable code, but records themselves are actually not always immutable.

I think the best comment on how to change the docs was this :

It would be good to word it so that no one can come away thinking “if I see a record, I know it’s immutable.”

Which is totally true. Records *can* be immutable, but not always (Like our example above).

To make each property be immutable, with an error, you have to make each property use the init keyword like so :

public record Person
{
    public string Name { get; init; }
    public int Age { get; init; }
}

Now I saw some writeups claim that you can simply do this :

public record Person
{
    string Name;
    int Age;
}

The thinking behind it is that every property on a record is automatically public (Kinda like an interface property), and then every property automatically has a get and init accessor placed on it if you don’t specify. This doesn’t work for me. I don’t know if it worked in a previous version, or people just wrote what they “thought” it should do, but this certainly doesn’t work on the latest SDK.

With that all being said this shorthand way of defining a record *does* work.

public record Person(string Name, int Age);

And this code now throws (two) errors :

var person = new Person(); // Throws an exception because you need to provide the constructor values
person.Name = "John Smith";//Throws an exception because you cannot assign an init only property after creation

There is a small caveat that for some reason, whenever I started writing this syntax, my Visual Studio would crash! This was version 16.7.1, once I upgraded to 16.7.4.. Suddenly I could write shorthand records without Visual Studio restarting on me which was nice.

If you read the arguments around immutability and you hear people say “It’s only immutable when it’s a positional record”, this is what they mean. Why positional? Because it’s dependent on the constructor positioning, for example this does not work :

var person = new Person //Error that we haven't used the constructor and given the Name. 
{
    Name = "John Smith", 
    Age = 30
};

If you want to be able to use the object initializer syntax instead of the constructor syntax, then you need to create your record completely, and provide the init only accessors on your properties that you want to be immutable…. It’s kinda… meh.

It may seem like I’m down on Records, and.. In some ways I am. There are lots of caveats that make me feel like the the entire premise of Records don’t quite work the way I would expect. I’m almost certain that in C# 10, there will be all sorts of improvements and then we will all be happy. Sort of like when (Value)Tuples were added to C# and you had to use .Item1 and Item2 etc and people were pretty horrified, then they added Named Tuples and everything was fine (More reading here : https://dotnetcoretutorials.com/2020/01/06/intro-to-c-tuples/).

Record Equality

All this talk of immutability with Records has meant that the equality features have sort of skipped by. And it’s interesting because you could create records, that are not immutable at all, just to use the equality features.

Let me demonstrate. If we create a class and a record that are essentially identical :

public class PersonClass
{
    public PersonClass(string name, int age)
    {
        this.Name = name;
        this.Age = age;
    }

    public string Name { get; init; }
    public int Age { get; init; }
}

public record Person(string Name, int Age);

Then say we have the following code :

var personClassA = new PersonClass("Jim", 30);
var personClassB = new PersonClass("Jim", 30);

Console.WriteLine(personClassA.Equals(personClassB));

var personRecordA = new Person("Jim", 30);
var personRecordB = new Person("Jim", 30);

Console.WriteLine(personRecordA.Equals(personRecordB));

The output will be False then True. Comparing two classes will check the reference of those two objects. Even if the values within those classes are the same, they will not be equal. Records are different in that equality is done using the values within that record. This is some compiler magic behind the scenes but essentially it’s comparing each of your properties one by one to make sure their *values* are the same.

You can override how a record checks it’s equality… But you cannot do so with the shorthand syntax. You need to write out the full record defintion again :

public record Person : IEquatable
{
    public Person(string name, int age)
    {
        this.Name = name;
        this.Age = age;
    }

    public string Name { get; init; }
    public int Age { get; init; }

    public virtual bool Equals(Person person2)
    {
        return this.Name == person2.Name;
    }
}

And then this code, even with the Age property being different :

var personRecordA = new Person("Jim", 30);
var personRecordB = new Person("Jim", 31);

Console.WriteLine(personRecordA.Equals(personRecordB));

Will still return True.

But this is somewhat daft because at this point, there is very little difference between a class and a record (If any at all to be honest). While records give you helpful ways to do immutability and compare by value.. You have to opt in to some less than ideal scenarios (Must use a constructor, must compare all property values for equality).

I would also note that this also does not work :

var personRecordA = new Person("Jim", 30);
var personRecordB = new Person("Jim", 30);

Console.WriteLine(personRecordA.Equals(personRecordB)); //Returns True
Console.WriteLine(personRecordA == personRecordA); //Returns False

For that you need to override the operator ==, which also requires you to override the operator !=

public record Person : IEquatable
{
    public Person(string name, int age)
    {
        this.Name = name;
        this.Age = age;
    }

    public string Name { get; init; }
    public int Age { get; init; }

    public virtual bool Equals(Person person2)
    {
        return this.Name == person2.Name;
    }

    public static bool operator==(Person person1, Person person2)
    {
        return person1.Equals(person2);
    }

    public static bool operator!=(Person person1, Person person2)
    {
        return !person1.Equals(person2);
    }
}

Note that this is even if you don’t write your own equality operator. Even by default, records do not override the == operator which.. IMO is maybe the wrong decision and probably one that can’t be changed now. But it’s very confusing when personA==personB returns false, but personA.Equals(personB) returns true.

Using The “with” Keyword With Records

Let’s say you have a record with a dozen properties, all init only, and you want to create a new record with only one change. You would have to write out a massively long constructor taking each property from the existing record, and then drop in your one change. Kinda messy.

But there is a helper using the “with” keyword.

var personRecordA = new Person("Jim", 30);
var personRecordB = personRecordA with { Age = 31 };

This means it takes all the values of personRecordA, and creates a new Record with the Age changed. This feature I actually find pretty handy and honestly I wouldn’t be surprised if this was extended to other types (classes and structs) because I think it’s very very handy.

Should You Use Records?

I’ll be the first to admit it’s hard for me to grasp records because in general, immutability hasn’t been big on my wishlist. I personally don’t develop all that much in F#, or use other languages with immutable “record” types, so it’s sometimes hard for my to envisage where I would use them.

But I think that’s made worse by the fact that Records act very differently simply based on whether you use a shorthand syntax or not. The promised features of records actually only happen if you use records in a very precise way, otherwise you’re more or less just using a class. And I think that’s somewhat the problem here, is that the immutability features of records, you can get in a class anyway.

Let me know in the comments where you’ve used Records, or your intended use cases because, as I say, my experience on the need for immutable records is very very small.

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

While mentoring a junior developer and trying to help them understand dependency injection, I came across a topic that I didn’t find a really great explanation out there on the internet. That is, when you end up with circular references while using dependency injection.

I found that there was some great resources at understanding circular references in general, and obviously great articles on the .NET Core dependency injection system, but not so many options when trying to jam them together. These were my explanations and example classes on how things work, so that hopefully they help someone else!

The Problem

Imagine a “simple” piece of code like below.

public class UserService
{
    private readonly PhoneService _phoneService;

    public UserService(PhoneService phoneService)
    {
        _phoneService = phoneService;
    }

    public string GetUserPhoneNumber()
    {
        var userId = 123;
        return _phoneService.GetPhoneNumberById(userId);
    }
}

public class PhoneService
{
    private readonly UserService _userService;

    public PhoneService(UserService userService)
    {
        _userService = userService;
    }

    public string GetPhoneNumberById(int phoneNumberId)
    {
        return "+64123123123";
    }

    public string GetUserPhoneNumber()
    {
        return _userService.GetUserPhoneNumber();
    }
}

Now the circular reference in this case is rather.. idiotic and I don’t expect anyone to realistically run into this sort of code in production, but it demonstrates the issue quite well.

You see, first someone created a UserService. This dealt with everything about a user. Next came a PhoneService, that dealt with everything to do with phone numbers. A smart developer then said, well given I have a UserService, and I want to get the phone number of a user, I’ll inject the PhoneService into the UserService, and then get the current users phone number.

But then along comes another developer. They say, well, if I have the phone number service, since I am dealing only with phone numbers, then I want to get the current users phone number. They noticed that there is already a method called “GetUserPhoneNumber” on the UserService, so they just inject that and call it. Remember, they may not even know that the way that UserService actually finds the phone number is by calling the PhoneService itself, but alas, it does.

And now we have a problem. For the UserService to be constructed, we need a PhoneService. But for a PhoneService to be constructed, we need a UserService. This is a circular reference. Luckily for us, .NET Core is pretty good at picking these issues up at the earliest possible runtime (But not compile time), and we usually end up with an exception.

A circular dependency was detected for the service of type 'UserService'.
UserService -> PhoneService -> UserService

It even directly points out the exact services which depend on each other. Note that in some cases, the circle could be much larger. For example

UserService -> PhoneService -> AnotherService -> UserService

But as long as the circle is enclosed, then you will get an exception.

The “Lazy” Fix / Service Locator

This is a terrible bandaid and I never recommend using this. Ever. It’s simply a bandaid to a problem that is very very easy to get wrong. Previously in .NET, you could do something like :

public class UserService
{
    private readonly Lazy<PhoneService> _phoneService;

    public UserService(Lazy<PhoneService> phoneService)
    {
        _phoneService = phoneService;
    }


    public string GetUserPhoneNumber()
    {
        var userId = 123;
        return _phoneService.Value.GetPhoneNumberById(userId);
    }
}

All the Lazy modifier did was not try and request the service until it was actually required. This meant that the UserService could be created without actually needing the PhoneService until the actual execution path was called, and so theoretically, while the constructors were running, they did not enter an infinite loop.

.NET Core now picks this up however and if you try any sort of the above with Lazy, it will stop you from doing so.

A circular dependency was detected for the service of type 'UserService'.
UserService -> System.Lazy -> PhoneService -> UserService

So then, people would just inject some sort of ServiceLocator. For example :

public class UserService
{
    private readonly ServiceLocator _serviceLocator;

    public UserService(ServiceLocator serviceLocator)
    {
        _serviceLocator = serviceLocator;
    }


    public string GetUserPhoneNumber()
    {
        var userId = 123;
        return _serviceLocator.Get<PhoneService>().GetPhoneNumberById(userId);
    }
}

This does compile and actually run, but again is simply a band aid to the problem. You still have a circular reference, it’s just that at some point you are killing the circle by using a ServiceLocator. Ugh.

I would put the use of “Factories” in here as well. I’ve seen people get around the problem by using a “PhoneServiceFactory” that itself uses a ServiceLocator or similar to construct the PhoneService for the UserService, so again you are breaking the circle. But again, you still have a circular reference you are just hacking your way out of it.

Kill The Reference

Far and away the best option for digging your way out of this hole is to not reference each other at all and if at all possible, have a one way reference between the services. So we *could* change our code to simple remove the GetUserPhoneNumber method from the PhoneService, and if you want a users phone number, you have to use UserService to get it.

public class UserService
{
    private readonly PhoneService _phoneService;

    public UserService(PhoneService phoneService)
    {
        _phoneService = phoneService;
    }

    public string GetUserPhoneNumber()
    {
        var userId = 123;
        return _phoneService.GetPhoneNumberById(userId);
    }
}

public class PhoneService
{
    public string GetPhoneNumberById(int phoneNumberId)
    {
        return "+64123123123";
    }
}

In our example, we really only had a circular reference out of convenience and not because we actually needed the method on both services. In some cases simply having a one way reference doesn’t work in which case…

Create A “Joining” Service

While not a great working example, what you’ll often have to do is create a “JoiningService”, for example a “UserPhoneNumberService”, where either the UserService and PhoneService both reference this service, or vice versa.

Often you can put all the shared functionality that both services need into this service. Or you can have this as an entry point to then call both the UserService and the PhoneService to get data instead of them calling each other.

Runtime Stack Overflows

If you have a circular reference that you attempt to get around using Factories, Lazy’s, ServiceLocators, or some other bandaid. What you might find is that you end up with one of the following errors.

System.InsufficientExecutionStackException
The program '[4176] iisexpress.exe' has exited with code -1073741819 (0xc0000005) 'Access violation'.

The most common reason is because you have registered a service as a factory in .NET Core DI :

services.AddTransient(s => new UserService(s.GetService()));

This is essentially a form of Lazy that the .NET Core DI container cannot pickup early on at runtime. What you are basically saying is “When you create the UserService, run this method”. Now “This method” is constructoring a new UserService, and trying to pull the PhoneService from the ServiceCollection. But because PhoneService references the UserService, we loop back on ourselves and execute this method again.

There aren’t really any safeguards against this because it’s hard to know at compile time exactly how things will be executed, but it’s a circular reference none the less.

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

Cloning objects in any programming language is tricky, but I think in C# that’s taken up an extra notch by giving you a couple of tools that look like they would probably solve your problem, but then not letting you know that it’s likely to only solve a very slim use case and nothing else. This guide is going to be half a guide on cloning, but also a quick refresher on what “cloning” actually means in the context of C#.

Shallow Clone vs Deep Clone

It’s worth starting at the basics. What is the difference between a shallow clone and a deep clone? (Also sometimes known as a shallow copy and a deep copy).

A shallow clone is a copy of an object that duplicates as little as possible. In C# this generally means that value types are duplicated, but reference types are not. Or as an example, let’s take the following object :

class Person
{
    public int Age { get; set; }
    public Person Father { get; set; }
    public Person Mother { get; set; }
}

If I made a shallow clone of this object and changed the age, the original object would not have it’s age changed. However, if I then changed a property on the cloned object’s father, then I would also affect the original object’s father because the reference isn’t cloned.

That may be a little confusing so thinking of it another way, in C#, when you do a shallow clone of an object, you are going “one level deep”, hence shallow. Any objects inside the object you want to clone are not themselves recursively cloned as well.

A deep clone is obviously the opposite. It keeps going down the tree and tries to clone all properties of your object, then the properties of that property etc.

Memberwise Clone

So if you’ve done any research at all into cloning in C#, you’ve probably come across the “memberwise” clone method. It’s available to every class but *only inside that class* as it’s a protected method of Object. You cannot call it on an object from another class.

For example :

class Person
{
    public string Name { get; set; }
    public Person Father { get; set; }
    public Person Mother { get; set; }

    public Person Clone()
    {
        return (Person)this.MemberwiseClone();
    }
}

However a quick look at the intellisense tells us something…

Creates a shallow copy of the current Object.

A shallow copy. Oof! So calling clone on this object will only shallow clone it, and not do a deep clone. If your object is purely primitives, then this can actually work for you and you can stop right here. But in most cases, we are looking to a deep clone. Even if for the sole reason that should someone add a property of another class here, then everything doesn’t suddenly break.

ICloneable Interface

So you might have also come across this interface called “ICloneable”. Unfortunately, it doesn’t really solve any problems an infact the documentation has this to say :

Because callers of Clone() cannot depend on the method performing a predictable cloning operation, we recommend that ICloneable not be implemented in public APIs.

Pretty stern words but it makes sense because if we look at how we might implement ICloneable.

class Person : ICloneable
{
    public string Name { get; set; }
    public Person Father { get; set; }
    public Person Mother { get; set; }

    public object Clone()
    {
        return this;
    }
}

Here we haven’t even cloned our object, we’ve just returned the same exact instance. While yes, we may expect a developer to know better, the point is that a caller doesn’t have any idea how the deep the clone goes, or if it’s even a clone at all. For this reason, people tend to stay away from the ICloneable interface.

Even if you get past that… It returns an object rather than a Person object which is annoying!

But with all that said, ICloneable doesn’t actually provide implementation details for cloning anyway. It just tells a caller “maybe call this and try your luck at getting a clone back”, but it doesn’t help a developer actually do a clone, shallow or deep.

Manually Deep Cloning

A sure fire way to know that you are deep cloning an object is to manually deep clone it yourself!

class Person
{
    public string Name { get; set; }
    public Person Father { get; set; }
    public Person Mother { get; set; }

    public Person Clone()
    {
        return new Person
        {
            Name = this.Name,
            Father = this.Father == null ? null : new Person { Name = this.Father.Name },
            Mother = this.Mother == null ? null : new Person { Name = this.Mother.Name }
        };
    }
}

In our clone method we are now creating new objects to completely clone our object and have no references to the original. This works great but it is time consuming. Any new property on this object means we have to modify our Clone method and re-test everything again.

On top of that, we are only going one level deep, for example we are not cloning our Father’s father, or our Mother’s mother.We may not need them for whatever we are then doing with our clones, but it’s also not a true “clone”. It’s just a clone of whatever we could be bothered mapping across!

With all those complaints out of the way however, it’s really not a bad option if it’s only a couple of classes that you really want to clone and they aren’t going to be modified that often.

Binary Serializer Cloning

An exceptionally common way of doing deep clones (Or atleast, more than just a shallow clone) is by serialising the data to another format and then back again.

Take this example of using a Binary Serializer on our Person class :

[Serializable]
class Person
{
    public string Name { get; set; }
    public Person Father { get; set; }
    public Person Mother { get; set; }

    public Person Clone()
    {
        IFormatter formatter = new BinaryFormatter();
        using (stream = new MemoryStream())
        {
            formatter.Serialize(stream, this);
            stream.Seek(0, SeekOrigin.Begin);
            return (Person)formatter.Deserialize(stream);
        }
    }
}

One very important thing to notice is that we’ve had to decorate our class with a [Serializable] attribute, without it we get :

Type 'Person' is not marked as serializable.

It’s also somewhat annoying to have to add this code to every class, so it’s far more likely that we create a static cloning service like this :

public static class CloningService
{
	public static T Clone<T>(this T source)
	{
		// Don't serialize a null object, simply return the default for that object
		if (Object.ReferenceEquals(source, null))
		{
			return default(T);
		}
		
		IFormatter formatter = new BinaryFormatter();
		using (stream = new MemoryStream())
		{
			formatter.Serialize(stream, source);
			stream.Seek(0, SeekOrigin.Begin);
			return (T)formatter.Deserialize(stream);
		}
	}
}

We still however have that issue of marking things as [Serializable].

JSON Serializer Cloning

This method is… Well.. a little rough but I’ve honestly found it works the best. You’ll first need to install the Newtonsoft.Json nuget package.

Install-Package Newtonsoft.Json

Then you can modify our cloning service like so :

public static class CloningService
{
	public static T Clone<T>(this T source)
	{
		// Don't serialize a null object, simply return the default for that object
		if (Object.ReferenceEquals(source, null))
		{
			return default(T);
		}

		var deserializeSettings = new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace };
		var serializeSettings = new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore };
		return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source, serializeSettings), deserializeSettings);
	}
}

And can I just say, everytime I’ve had to do this I think “Converting this to JSON and back again really isn’t great….”. But it just works. It handles everything you throw at it and is pretty much faultless.

In my opinion, if you are looking for a sure fire, re-useable way to clone objects in your code. This is it.

Reference Loops When Cloning

Eagle eyed readers will notice that in the above JSON cloning service, we have a line to handle reference looping. This is a very very common occurence, especially in models that are used as part of a DataModel where the two classes will reference each other. No matter how you decide to clone objects, you will always have issues where objects reference each other and any attempt to clone just spirals into an endless loop.

So even though in the above code, we solve it using a setting, it’s worth pointing out that no matter which way you decide to clone objects, this is going to always be a problem.

What’s Your Solution?

Think this page is full of hacks (it is!), and have a much better way to clone objects? Feel free to drop a comment below.

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

Lately I seem to have run into a tonne of these types of errors when trying to host .NET Core applications inside IIS

HTTP Error 502.5 - ANCM Out-Of-Process Startup Failure

and

HTTP Error 500.30 - ANCM In-Process Start Failure

And to be honest, they have been incredibly hard to debug. If you search for these errors on Google, you’ll find hundreds of stack overflow posts detailing people running into them, often with very little follow up on how they solved the issue. Sometimes they’ll even go as far to say “I re-installed everything and now it works” which in most cases, is not going to be viable. “Hey boss, let me just wipe this server real quick” generally doesn’t cut it.

But hopefully, fingers crossed, this will be the last blog post you’ll ever have to read on these error messages!

Why Are There Two Error Messages?

So first let’s touch on why there are two different messages (And error codes). Essentially, they are the exact same error but refer to different hosting models when running IIS infront of .NET Core. We won’t dive too deep into what these hosting models are, as at some point (.NET Core 2.1+ I believe) the default hosting model got swapped from Out-Of-Process to In-Process, so it very well could depend entirely on the version of .NET Core you are running.

Just know that for all practical purposes, these two error messages are the same so if you are following some blog post that is talking about one of these error messages, but you have the other, you can still follow along as it may well solve your problem.

Solution #1 – Incorrect Or Non-Existent .NET Core Hosting Bundle

So if you’re using something like Azure App Services that abstract away all the server management for you, then you can probably skip this, but if you are managing the server yourself (Or you’re trying to run a .NET Core application on your PC), then definitely read on.

If you followed our guide to running .NET Core on IIS (Which you definitely should) you would know that you need to install the .NET Core “Hosting Bundle” for .NET Core web apps to work inside IIS. This is also required even if you use self contained deployments. It is also required even if you install the .NET Core runtime on the machine. I’ll repeat, you cannot host .NET Core web applications inside IIS unless you install the hosting bundle.

If you are on your server and you aren’t sure if you have the hosting bundle installed, go to Add/Remove Programs in Windows and search for hosting :

If you don’t have this, then you can go here : https://dotnet.microsoft.com/download/dotnet-core/3.1 and download the hosting bundle :

It’s also important to note. Download the hosting bundle that matches the version of .NET Core you are running. I would presume that things are backwards compatible and if you download a newer version, it will work with older versions of .NET Core, but it’s super important to have atleast the same version as your actual code.

And finally. Restart your machine. I cannot make that any more clear. I cannot tell you how many people install everything under the sun and nothing seems to “work”, but it’s because they haven’t restarted. For the most part, you can get away with just an IISReset, but restarting the machine is often easier and just makes sure that you are restarting absolutely everything you need to.

For Shared Hosting, you may need to open a ticket with your provider. Again, I’ve seen providers only have the .NET Core 2 Hosting Bundle and people are trying to deploy .NET Core 3.1 applications. It pays to ask!

Still not working? Move onto Solution #2.

Solution #2 – .NET Core Startup Process Fails

This one took me an absolute lifetime to workout, but as it turns out, the .NET Core startup process has to start successfully before IIS can take over. That means if certain startup routines of .NET Core fail, then IIS doesn’t know how to handle the exception and just gives a generic error. Infact, that’s why it’s called an “ANCM Startup Failure”!

So what sort of things are we talking? Well for me, the most common one has been integrating with KeyVault. If you follow the official documentation here, it tells you to add it to your CreateHostBuilder method. CreateHostBuilder is ran on startup and needs to complete *before* IIS can take over, if for some reason your app cannot connect to KeyVault (Firewall, permissions etc), then your applicaiton will crash and IIS will have no option but to bail out as well.

Generally speaking, most of the times I see these ANCM startup failures has been when I’ve added code to the CreateHostBuilder method in my program.cs. Truth be told, it’s actually 100% of the time.

But how can we diagnose them? The easiest way is to actually run our application via Kestrel direct on the server. On a metal server (e.g. One you can RDP to), this means simply going to the folder where our application dlls are, and running “dotnet myapplication.dll” and seeing if it runs. What you should see is that the startup error is printed to the console and should point you in the right direction. Remember, in production configuration, firewalls, keys, and secrets could all be completely different so just because the application starts up fine on your local machine, on a remote machine it could completely blow up.

For sites hosted inside things like Azure App Services, you need to find a way to run the application manually yourself. On Azure, this means using Kudu, but on shared hosting services, you might be completely out of luck. If that’s you, you really have two options :

  • Open a support ticket to see if they can run your application manually in Kestrel like above, and hand you the error. (Again, this might be worth it to see if they even support the version of .NET Core you are intending to run).
  • Guess. Yes guess. Check your applications program.cs and how your HostBuilder is created. Start removing things and redeploying until you find the thing that is breaking it. If possible, create a simple hello world application and deploy it, if it also breaks, then it points more towards the hosting bundle than anything wrong with your startup code.

Debugging With stdout

Still need further debugging. Here’s another tip!

After publishing a .NET Core app, you will find in the publish directory there is a web.config with minimal information, but you should see something like so :

<aspNetCore processPath="dotnet" arguments=".\MyTestApplication.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />

Pretty obvious here, we just change stdoutLogEnabled=”false” to stdoutLogEnabled=”true” and redeploy. This should enable additional IIS logging to ./logs and allow us to debug further. Honestly, I’ve found this really really hit and miss. I’ve found that running the application directly from the console on the server to be much more helpful, but this is also an option if you have no other way.

Still Not Working?

Still not working? Or solved it a different way? Drop a comment below with a link to a GIT Repo and let the community help. This is honestly an infuriating error and I’ve had 20 year veteran programmers pull their hair out trying to solve it, so seriously drop a line. If you aren’t comfortable leaving a comment to your code, try wade[at]dotnetcoretutorials.com and I’ll see what I can do!

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

Getting Setup With C# 9

If you aren’t sure you are using C# 9 and/or you want to start using some of the new shiny features in the C# language, be sure to read our quick guide on getting setup with C# 9 and .NET 5. Any feature written about here is available in the latest C# 9 preview and is not a “theoretical” feature, it’s ready to go!

C# 9 Features

We are slowly working our way through all new C# 9 features, if you are interested in other new additions to the language, check out some of the posts below.

Free C# 9 Video Course

Are you one of those people that sees a big wall of text on a programming blog and instantly tunes out? Well you aren’t alone! In fact, I got hassled so much with people asking me “Can’t you just quickly share your screen and show me?” rather than reading a blog post, I decided I may as well quickly record the need to know bits of C# 9. So that’s what I’ve done!

My “What’s New In C# 9” course is completely free and will get you up and using C# 9 features in less than an hour (seriously!). Did I mention it’s FREE?

Watch For Free Now!

A Console Application Today

Start any new console application today from Visual Studio, and you’ll see something like this :

using System;

namespace TestTopLevelPrograms
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}

A bog standard console application that says Hello World. Not a heck of a lot going on here. But in many ways, it’s ever so slightly over engineered. Show this to a new programmer as their “first” program. And they’ll say “But what’s this namespace thing?” “What does static mean?” “What are args? Do I use them or?”. There’s just ever so much going on for such a simple program.

And taking it further, this isn’t limited to newbie programmers. It can be frustrating when you just want to “script” something, and you have all this boiler plate. And that’s what Top Level Programs solves.

Top Level Programs

Top level programs (also referred to as Top Level Statements) does away with this. We can take our simple application and turn it into :

using System;

Console.WriteLine("Hello World!");

That’s it! No more namespace, no more program class, just a bog standard simple script. In some ways, if you are a fan of using things like Linqpad, this is a very similar experience.

And I mean.. That’s it.. That’s top level programs! There really isn’t much more to it!

If you want to get started, as of today, there isn’t a Visual Studio template for writing everything top level (Well.. I mean that would just be a blank file). But if you create a new console application, then ensure you are using C# 9 by editing your .csproj to match the below :

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
    <LangVersion>9.0</LangVersion>
  </PropertyGroup>
</Project>

Then you should be able to essentially delete everything in your program.cs and start fresh.

Using Async

Want to use an sync method, no problem. Check this out :

using System;
using System.Threading.Tasks;

await MyAsyncMethod();
Console.WriteLine("Hello World!");

async Task MyAsyncMethod()
{
    await Task.Yield();
}

Using await tells the compiler that the compiled main entry point should also be async. And we are also showing off the fact that you can add in local method to this top level file to. It may just be the return of the one file wonder!

Using Args

Missing Args? No problem.

using System;
Console.WriteLine(args[0]);

Your args are still there, just not as obvious!

Who Is This For?

So finally, a quick note on who this is for. I don’t really feel like this is aimed at any one level of C# developer. While it’s helpful for newbies to find their footing in a more “scripting” environment, the fact that you can now just whip up a quick one file wonder without all the cruft of your regular console app is actually amazingly useful at any level.

I actually have a sneaking suspicion that those developers who fell in love with NodeJS with it’s simple one file APIs may also like the simplicity of this one. Imagine just being able to create a dead simple API that can return some lookup value, and it’s just a matter of opening up an empty file and typing.

Troubleshooting

If you get the following error :

The feature 'top-level statements' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.

It means you are using a version of C# less than 9 (Or atleast not with the latest preview version). Check out our quick guide on getting setup with using C# 9 and all it’s features here : https://dotnetcoretutorials.com/2020/08/07/getting-setup-with-c-9-preview/

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

Getting Setup With C# 9

If you aren’t sure you are using C# 9 and/or you want to start using some of the new shiny features in the C# language, be sure to read our quick guide on getting setup with C# 9 and .NET 5. Any feature written about here is available in the latest C# 9 preview and is not a “theoretical” feature, it’s ready to go!

C# 9 Features

We are slowly working our way through all new C# 9 features, if you are interested in other new additions to the language, check out some of the posts below.

Free C# 9 Video Course

Are you one of those people that sees a big wall of text on a programming blog and instantly tunes out? Well you aren’t alone! In fact, I got hassled so much with people asking me “Can’t you just quickly share your screen and show me?” rather than reading a blog post, I decided I may as well quickly record the need to know bits of C# 9. So that’s what I’ve done!

My “What’s New In C# 9” course is completely free and will get you up and using C# 9 features in less than an hour (seriously!). Did I mention it’s FREE?

Watch For Free Now!

What We Have Currently

So before we jump into C# 9 and Init Only Properties, I thought let’s take a quick look on the problem this feature is actually trying to solve. In some classes, typically “model” classes, we want to make properties publicly readable, but not be able to be set outside our class. So something like this is pretty common :

public class Person
{
    public string Name { get; private set; }
}

We can now set the property of Name anywhere inside the class, for example in a constructor or from a method pretty easily :

public class Person
{
    public Person(string name)
    {
        this.Name = name;
    }

    public void SetName(string name)
    {
        this.Name = name;
    }

    public string Name { get; private set; }
}

But what’s harder now is that we can’t use an Object Initializer instead of a constructor, even if we are “newing” up the object for the first time, for example :

var person = new Person
{
    Name = "Jane Doe" // Compile Error 
};

No bueno! We get the following error :

The property or indexer 'Person.Name' cannot be used in this context because the set accessor is inaccessible

It’s not the end of the world but pretty annoying none the less.

But there’s actually another bigger issue. That is that in some cases, we may want a property to be set inside a constructor *or* object initialization and then not be changed after being created. Essentially, an immutable property.

There’s actually nothing that stops us from modifying the property after creation from inside the class. For example a private method can be called to edit the property just fine like so :

public class Person
{
    public void SetName(string name)
    {
        this.Name = name;
    }

    public string Name { get; private set; }
}

And that’s the larger problem here. I think for many years C# developers have used “private set;” as a way to half achieve immutability by only setting that property within a constructor or similar, and that sort of works for libraries where you don’t have access to the actual source code, but there’s nothing actually signalling the intent of the original developer that this property should *only* be set on object creation and never again.

Introducing Init-Only Properties

Let’s take our Person class and modify it like so :

public class Person
{
    public string Name { get; init; }
}

Notice how we change our “set” to “init”. Pretty easy, now let’s look at how that might affect code :

var person = new Person();
person.Name = "Jane Doe"; // Compile Time Error

Immediately the compiler throws this error :

Init-only property or indexer 'Person.Name' can only be assigned in an object initializer, or on 'this' or 'base' in an instance constructor or an 'init' accessor

OK so far, pretty similar to the “private set” we were using before. But notice that object initializers now do work :

var person = new Person
{
    Name = "Jane Doe" // Works just fine!
};

How about in the constructor?

public class Person
{
    public Person(string name)
    {
        this.Name = name;
    }

    public string Name { get; init; }
}

Also compiles fine! And what about in a method on a class :

public class Person
{
    public void SetName(string name)
    {
        this.Name = name; // Compile Error
    }

    public string Name { get; init; }
}

Boom! Everything blows up. So we’ve got that immutability we’ve always been after with private set, but it’s actually enforced this time!

Init is a relatively small change on the face of it, it’s just an extra keyword for properties, but it does make complete sense why it’s been added and I’m sure will be a welcome change for all C# developers.

Comparison With Readonly Variables

So I know someone on Twitter will definitely shoot me down for saying that we “finally” have immutable properties when we’ve had the “readonly” keyword for quite some time now. But there’s some differences that really make the init change a huge quality of life addition.

So this does create an “immutable property” :

public class Person
{
    public Person(string name)
    {
        _name = name;
    }

    private readonly string _name;
    public string Name => _name;
}

However you must now use the constructor, you cannot do this using object initializers :

var person = new Person
{
    Name = "Jane Doe"
};

Also the fact that you have to create a backing variable for the property is rather annoying so… I still love the init addition.

Side note. Someone pointed out in the comments that you can create a hidden backing field just by adding a single get accessor :

public class Person
{
    public string Name { get; } 
    
    Person(string name) 
        => Name = name;
} 

So this also works and is pretty close to immutability, but again, no object initializer (And no really signally the intent I think). But shout out to Antão!

I should also note that init properties actually work well with readonly variables if you actually do need it since init is only run at object construction which fits the readonly paradigm just fine. So as an example, this compiles and runs fine :

public class Person
{
    private readonly string _name;

    public string Name
    {
        get => _name;
        init => _name = value;
    }
}

Troubleshooting

If you get the following error :

The feature 'init-only setters' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.	

It means you are using a version of C# less than 9 (Or atleast not with the latest preview version). Check out our quick guide on getting setup with using C# 9 and all it’s features here : https://dotnetcoretutorials.com/2020/08/07/getting-setup-with-c-9-preview/

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

Getting Setup With C# 9

If you aren’t sure you are using C# 9 and/or you want to start using some of the new shiny features in the C# language, be sure to read our quick guide on getting setup with C# 9 and .NET 5. Any feature written about here is available in the latest C# 9 preview and is not a “theoretical” feature, it’s ready to go!

C# 9 Features

We are slowly working our way through all new C# 9 features, if you are interested in other new additions to the language, check out some of the posts below.

Free C# 9 Video Course

Are you one of those people that sees a big wall of text on a programming blog and instantly tunes out? Well you aren’t alone! In fact, I got hassled so much with people asking me “Can’t you just quickly share your screen and show me?” rather than reading a blog post, I decided I may as well quickly record the need to know bits of C# 9. So that’s what I’ve done!

My “What’s New In C# 9” course is completely free and will get you up and using C# 9 features in less than an hour (seriously!). Did I mention it’s FREE?

Watch For Free Now!

What We Currently Have

I remember reading the words “relational pattern matching” and kinda skipping over the feature because I wasn’t really sure what it was (And so, my developer brain said it can’t be that important!). But when I eventually found actual examples of it in action, I couldn’t believe that C# hadn’t had this feature yet.

So first, let’s mock up a problem in C# 8 that we should be able to solve with Relational Pattern Matching in C# 9 to actually be able to see the power.

Let’s take the following code :

int myValue = 1;

if (myValue <= 0)
    Console.WriteLine("Less than or equal to 0");
else if (myValue > 0 && myValue <= 10)
    Console.WriteLine("More than 0 but less than or equal to 10");
else
    Console.WriteLine("More than 10");

How could we improve it? Well, I would probably still use the If/Else jumble from above in most cases just for it’s simplicity, but if you wanted to, you could use the Pattern Matching introduced in C# 7 with a switch statement. That would look something like this :

switch(myValue)
{
    case int value when value <= 0:
        Console.WriteLine("Less than or equal to 0");
        break;
    case int value when value > 0 && value <= 10:
        Console.WriteLine("More than 0 but less than or equal to 10");
        break;
    default:
        Console.WriteLine("More than 10");
        break;
}

Not bad but we don’t really add anything to the If/Else statements, in fact we actually add even more complexity. If we are using C# 8, then we can use Switch Expressions (A great introduction here if you’ve never seen Switch Expressions before : https://dotnetcoretutorials.com/2019/06/25/switch-expressions-in-c-8/). That would instead look something like :

var message = myValue switch
{
    int value when value <= 0 => "Less than or equal to 0",
    int value when value > 0 && value <= 10 => "More than 0 but less than or equal to 10",
    _ => "More than 10"
};

Console.WriteLine(message);

This actually looks pretty good. But there is *so* much verbose stuff going on here that surely we can clean up right?

Adding The “is”/”and” Keywords

This actually isn’t specific to our example, but C# 9 has introduced the “is” and “and” keywords (We’re going to do an entire article on these in the future because there is actually some really cool stuff you can do). And these can actually help us here, we can now change this :

if (myValue > 0 && myValue <= 10)
    Console.WriteLine("More than 0 but less than or equal to 10");

To this :

if (myValue is > 0 and <= 10)
	Console.WriteLine("More than 0 but less than or equal to 10");

It’s just some sugar around saying “take this value and then I can do 1 to N statements on it all at once”. In long IF statements where you check multiple different options for a single variable/property, this is a huge help.

So obviously we can rewrite our If/Else statement from above to look like so :

if (myValue <= 0)
    Console.WriteLine("Less than or equal to 0");
else if (myValue is > 0 and <= 10)
    Console.WriteLine("More than 0 but less than or equal to 10");
else
    Console.WriteLine("More than 10");

And while that middle statement is a bit tidier, overall we are still writing quite a bit.

Relational Pattern Matching In Switch Statements/Expressions

Now we are cooking with gas. In C# 9, we can now turn this big case statement :

case int value when value > 0 && value <= 10:

Into this :

case > 0 and <= 10:

So we can do away with setting our variable for the pattern, and then add in our new “and” keyword to make things even tidier. That turns our entire switch statement into this :

switch(myValue)
{
    case <= 0:
        Console.WriteLine("Less than or equal to 0");
        break;
    case > 0 and <= 10:
        Console.WriteLine("More than 0 but less than or equal to 10");
        break;
    default:
        Console.WriteLine("More than 10");
        break;
}

Pretty tidy! But we can take it further with our switch expression :

var message = myValue switch
{
    <= 0 => "Less than or equal to 0",
    > 0 and <= 10 => "More than 0 but less than or equal to 10",
    _ => "More than 10"
};

Console.WriteLine(message);

Holy moly that’s tidy! And that’s relational pattern matching with C# 9!

Troubleshooting

If at any point you get the following errors :

The feature 'and pattern' is currently in Preview and *unsupported*. 
The feature 'relational pattern' is currently in Preview and *unsupported*. 

It means you are using a version of C# less than 9. Check out our quick guide on getting setup with using C# 9 and all it’s features here : https://dotnetcoretutorials.com/2020/08/07/getting-setup-with-c-9-preview/

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

Getting Setup With C# 9

If you aren’t sure you are using C# 9 and/or you want to start using some of the new shiny features in the C# language, be sure to read our quick guide on getting setup with C# 9 and .NET 5. Any feature written about here is available in the latest C# 9 preview and is not a “theoretical” feature, it’s ready to go!

C# 9 Features

We are slowly working our way through all new C# 9 features, if you are interested in other new additions to the language, check out some of the posts below.

Free C# 9 Video Course

Are you one of those people that sees a big wall of text on a programming blog and instantly tunes out? Well you aren’t alone! In fact, I got hassled so much with people asking me “Can’t you just quickly share your screen and show me?” rather than reading a blog post, I decided I may as well quickly record the need to know bits of C# 9. So that’s what I’ve done!

My “What’s New In C# 9” course is completely free and will get you up and using C# 9 features in less than an hour (seriously!). Did I mention it’s FREE?

Watch For Free Now!

What Is Target Typing?

I’m going to be honest, before C# 9 where they talk about “Improved” Target Typing, I had never actually heard of the term before. But it’s actually very simple. It’s basically a way to say “given the context of what I’m doing, can we infer the type”. The use of the “var” keyword is an example of target typing. The use of var is actually a good example here because it’s actually almost the reverse of the improvements to target typing in C# 9, but let’s jump into those.

Target Typed New Expressions

Target Typed New Expressions is basically just a fancy way of saying that we don’t have to say the type after the new() expression…. That probably doesn’t make it anymore clearer, but in here’s a sample piece of code :

class Person
{
    public string FirstName { get; set; }
}

class MyClass
{
    void MyMethod()
    {
        Person person = new Person();
    }
}

Now in C# 9, you can do :

class Person
{
    public string FirstName { get; set; }
}

class MyClass
{
    void MyMethod()
    {
        Person person = new(); //<-- This!
    }
}

Since you’ve already defined the type for your variable, it can infer that when you call new() without a type, you’re trying to new up the exact type.

It even works with constructors with parameters!

class Person
{
    public Person(string firstName)
    {
        this.FirstName = firstName;
    }
    public string FirstName { get; set; }
}

class MyClass
{
    void MyMethod()
    {
        Person person = new("John");
    }
}

Unfortunately there is a really big caveat. Constructors (I feel anyway) have almost become the minority in my code, especially because of the heavy use of Dependency Injection in todays coding. So typically when I am newing up an object, I am setting properties at the same time like so :

Person person = new Person
{
    FirstName = "John"
};

But of course this doesn’t work :

Person person = new
{
    FirstName = "John"
};

Because writing new like that without a type, then straight into curly’s tells C# you are creating an “anonymous” object. Interestingly in the current C#9 Preview with Visual Studio, you can do the “double up” approach like so :

Person person = new()
{
    FirstName = "test"
};

Intellisense *does not* work right now when doing this (e.g. It won’t auto complete “FirstName” for me), but once it’s written, it will compile. I chuckle because at the moment if you tried this in C#8, it would gray out the () because they aren’t needed. And typically in a code review someone will add a nit that “Hey, you don’t need the parenthesis”, but now I guess there is a reason to have them!

Another huge caveat is the use of the “var” keyword. For obvious reasons, this doesn’t work :

var person = new();

As I mentioned earlier, this is almost like using var, but coming from the other side. If your code doesn’t use the var keyword that often, then this may be of use, but for me, I almost exclusively use var these days when newing up objects, so it’s not going to be a common tool in my arsenal.

That being said, cases where you cannot use var (Class level properties, returning new objects from a method etc), this fits perfectly.

Target Typing Conditional Operators

What we are about to talk about *should* work in C# 9, but under the current preview doesn’t. Apparently in a previous preview version it did but.. Right now it’s a bit busted. Frustrating! But we’ll still talk about it anyway because it’s under the umbrella of “Target Typing”.

Target typed conditional operators are basically the compiler looking for ways to make your null-coalescing operator (??) work. For example the following code :

class Program
{
    static void Main(string[] args)
    {
        Cat cat = null;
        Dog dog = new Dog();
        IAnimal animal = cat ?? dog;
    }
}

interface IAnimal
{

}

class Dog : IAnimal
{

}

class Cat : IAnimal
{

}

Notice how Cat and Dog both inherit from the same interface (IAnimal), and we are checking if Cat is null, then return Dog into a variable with a type of “IAnimal”. Right now in C# 8 (And.. C# 9 Preview 7), this doesn’t work and the compiler complains. But it makes total sense for this code to work because the developers intent is clear, and it doesn’t break any existing paradigms with the language.

For example doing this does work in all versions of C#:

Cat cat = null;
Dog dog = new Dog();
IAnimal animal = cat;
if (animal == null)
    animal = dog;

So it’s really just allowing the ?? operator to do this for us.

Another example not using classes would be something such as :

Dog dog = null;
int? myVariable = dog == null ? 0 : null;

This fails because there is no conversion between 0 and null. But we are casting it back to a nullable integer so clearly there is a common base here and the developers intent is pretty clear. In fact this does work if you do something such as :

Dog dog = null;
int? myVariable = dog == null ? 0 : default(int?);

Or even

Dog dog = null;
int? myVariable = dog == null ? (int?)0 : null;

So again, this is all about wrapping some sugar around this to do things we already do and make developers lives easier.

Again I must stress that the improved target typing for conditional operators are not quite in the preview yet, but should be there very soon.

Troubleshooting

Just a quick note for this feature. If you see :

The feature 'target-typed object creation' is currently in Preview and *unsupported*.

Then you *must* have the latest preview SDK installed and your csproj file updated to handle C# 9. More info here : https://dotnetcoretutorials.com/2020/08/07/getting-setup-with-c-9-preview/

 

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.