Quite often I come across the need for small immutable data structures. Others would probably use Tuples in these cases, but I really dislike that Tuples don't read nicely and don't express that much meaning. A Value2
of int
doesn't tell me anything.
An example would be creating a lookup table (Dictionary) for a combination of two properties, i.e. Name
and Rating
.
The shortest way to make an immutable struct for these cases that 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' in here that I would like to get rid of. I could make it a lot more readable when I would just expose 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 barely any syntactic fat. The big disadvantage is of course that it is not immutable, with all it's dangers.
In the ideal case I would just like to have a special type for this, with the real bare minimum of definition, like:
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 something closer to the example on the bottom, to reduce the amount of syntactic fat for a very simple immutable struct?
As of 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'd strongly advise implementing IEquatable<Key>
, mind you.
Note that as you're dealing with a struct, you'll still be able to write:
Key key = new Key();
Console.WriteLine(key.Rating); // 0
... which may not be a problem, but generally needs considering at least.
Before C# 6, I'd actually go even longer than your current code, in order to write the 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 clearly "meant to be immutable" - if you've got a writable property, even if the setter is only private, that doesn't convey the right impression IMO. (Although it's worth noting that immutability in structs is always a little bit of a pretense, given that you can assign to this
in members...)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With