Welcome Improvements in C# 10 – iProgrammer

Welcome Improvements in C# 10

The changes may be small, but we still need to keep up-to-date. How does moving to version 10 change C#? A look at three features that make it really worthwhile.

There isn’t much that can be changed in C# without worrying about backward compatibility, but there are some nice additions in C# 10.

Lambdas

It has been a minor annoyance that you have to specify a type for a lambda when the type is fairly obvious from its parameters. Now the compiler will infer one of the standard generic function types and apply it for you. For example, you used to have to write:

HelloType HelloInst = (param1) =>
{
    MessageBox.Show("Hello delegate World" +
                               param1.ToString());
  return ++param1;
};

where HelloType was defined as a delegate somewhere else in the program. Now you can write:

var HelloInst = (int param1) =>
{
    MessageBox.Show("Hello delegate World" +
                               param1.ToString());
  return ++param1;
};

and the compiler will work out that HelloInst is an instance of Func<int,int>.  If you hover over HelloInst then the compiler will tell you its type.

This sort of thing also works with method groups. Where you had to write

HelloType Hello= MyObject.myfunction;:

you can now write:

var Hello= MyObject.myfunction;:

as long as HelloInst isn’t overloaded. Again the compiler will guess that Hello is Func<int,int>.

Not being able to declare a return type for a lambda was sometimes an irritation when different types could be returned and now you can specify the return type as you would for a method:

var HelloInst = int (int param1) =>
{
    MessageBox.Show("Hello delegate World" +
                               param1.ToString());
  return ++param1;
};

Notice the int in front of the parameters.

Finally you have long been able to apply attributes to methods but not lambdas now you can. If you set an attribute target to Method you can annotate a lambda.

[myattribute]
var HelloInst = int (int param1) =>
{
    MessageBox.Show("Hello delegate World" +
                               param1.ToString());
  return ++param1;
}

The only problem is that the attribute will not be called when the lambda is – so it doesn’t really work as an attribute.

Structs

The biggest change to structs is permission to create a parameterless constructor. All structs have a default parameterless constructor that sets all of the fields to default values appropriate for their type. This prohibited you from defining your own parameterless constructor, but now you can. If you don’t the fields are set to defaults, but if you do you can see the fields to defaults of your own choice. For example, if you define:

public struct Point
{
    public int x, y;
}

then when you create a Point:

Point p;

the fields are set to zero. However, if you add a constructor:

public struct Point
{
public int x, y;
public Point()
{
x = 100;
y = 100;
}
}

You can create a struct with x and y set to 100 using:

Point p=new Point();

Another case of structs being second class citizens has been fixed as now they can be records too: In many ways records are an alternative to structs with reference semantics, but now you can have the convenience of records, but with value semantics. For example, instead of:

public record Staff
{ public string name { get; init; } public int age { get; set; }
} 

which creates a record class you can use:

public record struct Staff
{ public string name { get; init; } public int age { get; set; }
} 

which creates a record struct.

One of the nice things about records is the with expression that allows you to create partially initialized records. You can now use this will all structs including record structs: For example:

Staff you = me with { name = "harry" };

This creates a copy of the me record but with the name changed to harry. The with expression creates a completely new copy of the struct or record then uses the object initializer to change any fields mentioned and then sets the variable to refer to the new object.

Pattern Matching

There are some other small improvements but the ability to shorten nested property patterns will be useful to anyone over using pattern matching. Instead of

is {Address:{City: “London”}}

you can write the more natural:

is (Address.City: “London”}

There is also a major preview included that you can enable as an option. If it makes it into C# 11 it might make generics much more powerful by allowing operators on generic types, among other things.

  • Mike James, Founder and Chief Editor of I Programmer is a prolific author. In Deep C#: Dive Into Modern C#, published in September 2021, he provides a “deep dive” into various topics that are important or central to the language. By exploring the motivation behind these key concepts, which is so often ignored in the documentation, the intention is to be thought-provoking and to give developers confidence to exploit C#’s wide range of features.

 

More Information

Welcome to C# 10

Related Articles

Microsoft Releases .NET 6 And Visual Studio 2022

Developer Preview Of .NET 6 Released

C# 9 and F# 5 Released With .NET 5

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

 


Google Summer Of Code Opens Up To Non-Students

19/11/2021

Google has decided to broaden the scope of the Google Summer of Code Program beginning in 2022. The change means that anyone aged 18 years and over who is a newcomer to open source can apply. Two othe [ … ]


+ Full Story


GitHub Announces Improvements At Universe 2021

04/11/2021

GitHub Universe 2021 has now ended, with a wide ranging set of improvements and new features announced at the conference. These ranged from making the new GitHub Issues a public beta, through improved [ … ]


+ Full Story

More News

Comments

or email your comment to: comments@i-programmer.info

<ASIN:1871962714>

<ASIN:B09FTLPTP9>

HelloType HelloInst = (param1) =>
{
MessageBox.Show("Hello delegate World" + param1.ToString());
  return ++param1;
};