在C#中编写不可变结构的最短方法

Dir*_*oer 7 c# syntax immutability

我经常遇到小型不可变数据结构的需求.其他人可能会在这些情况下使用Tuples,但我真的不喜欢Tuples不能很好地阅读并且没有表达那么多意义.一Value2int并没有告诉我任何事情.

一个例子是为两个属性的组合创建一个查找表(Dictionary),即NameRating.

为我知道的这些案例制作不可变结构的最短方法是:

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 );
Run Code Online (Sandbox Code Playgroud)

在我看来,这里仍有很多"语法脂肪",我想摆脱它.当我直接暴露字段时,我可以使它更具可读性.

public struct Key
{
    public string   Name;
    public int      Rating;
}

// useage
var key = new Key { Name = "MonorailCat", Rating = 5 };
Run Code Online (Sandbox Code Playgroud)

我非常喜欢这种语法,因为几乎没有任何语法上的脂肪.当然,最大的缺点是它不是一成不变的,具有所有危险.

在理想的情况下,我只想有一个特殊的类型,真正的最低定义,如:

public immutable struct Key
{
    string  Name;
    int     Rating;
}

// useage (needs compiler magic)
var key = new Key( Name: "MonorailCat", Rating: 5 );
Run Code Online (Sandbox Code Playgroud)

是否有一个真实世界的解决方案更接近于底部的示例,以减少非常简单的不可变结构的语法脂肪量?

Jon*_*eet 15

从C#6开始,您可以编写相当紧凑的struct初始值设定项:

public struct Key
{
    public string Name { get; }
    public int Rating { get; }

    public Key(string name, int rating)
    {
        this.Name = name;
        this.Rating = rating;
    }
}
Run Code Online (Sandbox Code Playgroud)

......至少短得多.我强烈建议IEquatable<Key>您实施,请注意.

请注意,当您处理结构时,您仍然可以编写:

Key key = new Key();
Console.WriteLine(key.Rating); // 0
Run Code Online (Sandbox Code Playgroud)

......这可能不是问题,但通常至少需要考虑.

在C#6之前,我实际上要比当前代码更长,以便将属性写为只读属性:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我觉得这使得它更清楚地"意味着不可改变" - 如果你有一个可写的财产,即使这个设定者只是私人的,也不能传达IMO的正确印象.(虽然值得注意的是结构中的不变性总是有点假装,因为你可以分配给this成员......)