The shortest way to write an immutable structure in C #

Quite often, I come across the need to create small, immutable data structures. Others will probably use Tuples in these cases, but I really dislike the fact that Tuples do not read beautifully and do not express such great significance. A Value2 of int doesn't tell me anything.

An example would be to create a lookup table (Dictionary) for a combination of two properties, that is, Name and Rating .

The shortest way to make an immutable structure for these cases, which I know of, is this:

 public struct Key { public string Name { get; private set; } public int Rating { get; private set; } public LolCat(string name, int rating) : this() { Name = name; Rating = rating; } } // useage var key = new Key( "MonorailCat", 5 ); 

In my opinion, there is still a lot of "syntactic fat" that I would like to get rid of. I could make it more readable when I just open the fields directly.

 public struct Key { public string Name; public int Rating; } // useage var key = new Key { Name = "MonorailCat", Rating = 5 }; 

I really like the syntax of this because there is almost no syntactic fat. The big flaw, of course, is that it is not immutable, with all its dangers.

In the ideal case, I would like to have a special type for this, with a real minimal definition, for example:

 public immutable struct Key { string Name; int Rating; } // useage (needs compiler magic) var key = new Key( Name: "MonorailCat", Rating: 5 ); 

Question

Is there a real world solution that is closer to the example below to reduce the amount of syntactic fat for a very simple immutable structure?

+5
source share
3 answers

With C # 6, you can write fairly compact struct initializers:

 public struct Key { public string Name { get; } public int Rating { get; } public Key(string name, int rating) { this.Name = name; this.Rating = rating; } } 

... which is at least significantly shorter. I highly recommend implementing IEquatable<Key> , mind you.

Note that since you are dealing with a structure, you can still write:

 Key key = new Key(); Console.WriteLine(key.Rating); // 0 

... which may not be a problem, but, as a rule, it is necessary to consider at least.

Before C # 6, I actually go even longer than your current code to write properties as read-only properties:

 public struct Key { private readonly string name; private readonly int rating; public string Name { get { return name; } } public int Rating { get { return rating; } } public Key(string name, int rating) { this.name = name; this.rating = rating; } } 

I feel this makes it more understandable โ€œmeaning to be unchangedโ€ - if you have the ability to record, even if the setter is only closed, this does not convey the correct IMO impression. (Although it is worth noting that immutability in structures is always a bit of an excuse, given that you can assign this to members ...)

+13
source

AFAIK, the shortest you can write, uses readonly, which is hardly shorter than your structure using properties:

 public struct Key { public readonly string Name; public readonly int Rating; public Key(string name, int rating){ Name = name; Rating = rating; } } var key = new Key("MonorailCat", 5); 
+2
source

C # 7.2 has a readonly structure.

 readonly public struct ReadonlyPoint3D { public ReadonlyPoint3D(double x, double y, double z) { this.X = x; this.Y = y; this.Z = z; } //setters would not compile public double X { get; } public double Y { get; } public double Z { get; } private static ReadonlyPoint3D origin = new ReadonlyPoint3D(); public static ref readonly ReadonlyPoint3D Origin => ref origin; public ReadonlyPoint3D Scale(double factor) { /* all fail compilation X *= factor; Y *= factor; Z *= factor; */ return new ReadonlyPoint3D(X * factor, Y * factor, Z * factor); } } 

The compiler ensures that all members are read-only. This was passed as "in", not a copy of the recipient, which is usually more efficient.

Reference

+1
source

Source: https://habr.com/ru/post/1202336/


All Articles