如何有效地实现不可变类型

发布于 2024-12-01 21:47:16 字数 344 浏览 0 评论 0原文

在编写 C# 代码时,我经常发现自己实现了不可变类型。 我总是最终编写大量代码,我想知道是否有更快的方法来实现它。

我通常写的内容:

public struct MyType
{
  private Int32 _value;
  public Int32 Value { get { return _value;} }

  public MyType(Int32 val)
  {
     _value = val;
  }
}

MyType alpha = new MyType(42);

当字段数量增加并且需要大量输入时,这会变得相当复杂。 有没有更有效的方法来做到这一点?

When coding C# I often find myself implementing immutable types.
I always end up writing quite a lot of code and I am wondering whether there is a faster way to achieve it.

What I normally write:

public struct MyType
{
  private Int32 _value;
  public Int32 Value { get { return _value;} }

  public MyType(Int32 val)
  {
     _value = val;
  }
}

MyType alpha = new MyType(42);

This gets fairly complicated when the number of fields grows and it is a lot of typing.
Is there a more efficient way for doing this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

空城缀染半城烟沙 2024-12-08 21:47:16

我建议编写更少代码的唯一方法是使用 ReSharper 之类的工具来自动生成代码。如果您从以下内容开始:

public class MyType
{
    private int _value;
}

您可以生成“只读属性”以给出:

public class MyType
{
    private int _value;
    public int Value{get {return _value;}}
}

后跟生成构造函数以给出:

public class MyType
{
    private int _value;
    public int Value{get {return _value;}}

    public MyType(int value)
    {
        _value = value;
    }
}

生成步骤总共是 8 个按键。


如果你真的想要一个不可修改的不可变类,我会这样声明它:

public sealed class MyType
{
    public int Value{get {return _value;}}
    private readonly int _value;

    public MyType(int value)
    {
        _value = value;
    }
}

这使得该类不可派生(意味着子类无法修改其内部状态),并且 _value 属性只能分配施工期间。不幸的是,ReSharper 没有针对此模式的代码生成功能,因此您仍然需要手动构建(大部分)它。

The only way I can suggest of writing less code is to use something like ReSharper to auto-generate the code for you. If you start with something like:

public class MyType
{
    private int _value;
}

you can then generate "read-only properties" to give:

public class MyType
{
    private int _value;
    public int Value{get {return _value;}}
}

followed by generate constructor to give:

public class MyType
{
    private int _value;
    public int Value{get {return _value;}}

    public MyType(int value)
    {
        _value = value;
    }
}

The generation steps are 8 key presses in total.


If you really want an unmodifiable immutable class, I would declare it as such:

public sealed class MyType
{
    public int Value{get {return _value;}}
    private readonly int _value;

    public MyType(int value)
    {
        _value = value;
    }
}

This makes the class non-derivable (meaning that a sub-class cannot modify its inner state), and the _value property assignable only during construction. Unfortunately, ReSharper doesn't have code generation for this pattern, so you would still have to construct (most of) it manually.

岁吢 2024-12-08 21:47:16

您可以使用自动属性和私有设置器稍微简化它,如下所示:

public struct MyType
{  
  public Int32 Value { get; private set; }

  public MyType(Int32 val)
  {
     Value = val;
  }
}

You could simplify it a little with automatic properties and a private setter as below:

public struct MyType
{  
  public Int32 Value { get; private set; }

  public MyType(Int32 val)
  {
     Value = val;
  }
}
萌︼了一个春 2024-12-08 21:47:16

救援代码片段!
将此 xml 保存为“immutable.snippet”,然后转到 Visual Studio,选择“工具”、“代码片段管理器”并导入它。就是这样!现在写“immutable”并按 TAB 两次,你就得到了不可变类型。

代码片段中的实际代码基于@adrianbanks 的答案。

<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
      <Title>Immutable type (C#)</Title>
      <Author>Alfonso Cora</Author>
      <Description>Creates an immutable type</Description>
      <HelpUrl>http://stackoverflow.com/questions/7236977/how-to-efficiently-implement-immutable-types</HelpUrl>
      <Shortcut>immutable</Shortcut>
    </Header>
    <Snippet>
      <Declarations>
        <Literal Editable="true">
          <ID>type</ID>
          <ToolTip>The type on which this immutable type is based.</ToolTip>
          <Default>int</Default>
          <Function>
          </Function>
        </Literal>
        <Literal Editable="true">
          <ID>class</ID>
          <ToolTip>The name of the immutable type.</ToolTip>
          <Default>MyImmutableType</Default>
          <Function>
          </Function>
        </Literal>
      </Declarations>
      <Code Language="csharp"><![CDATA[public sealed class $class$
{
    public $type$ Value{get {return _value;}}
    private readonly $type$ _value;

    public $class$($type$ value)
    {
        _value = value;
    }
}]]></Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

Code snippets at the rescue!
Save this xml as "immutable.snippet", then go to Visual Studio, select Tools, Code Snippets Manager and import it. That's it! Now write "immutable" and hit TAB twice and you have your immutable type.

The actual code in the snippet is based on @adrianbanks answer.

<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
      <Title>Immutable type (C#)</Title>
      <Author>Alfonso Cora</Author>
      <Description>Creates an immutable type</Description>
      <HelpUrl>http://stackoverflow.com/questions/7236977/how-to-efficiently-implement-immutable-types</HelpUrl>
      <Shortcut>immutable</Shortcut>
    </Header>
    <Snippet>
      <Declarations>
        <Literal Editable="true">
          <ID>type</ID>
          <ToolTip>The type on which this immutable type is based.</ToolTip>
          <Default>int</Default>
          <Function>
          </Function>
        </Literal>
        <Literal Editable="true">
          <ID>class</ID>
          <ToolTip>The name of the immutable type.</ToolTip>
          <Default>MyImmutableType</Default>
          <Function>
          </Function>
        </Literal>
      </Declarations>
      <Code Language="csharp"><![CDATA[public sealed class $class$
{
    public $type$ Value{get {return _value;}}
    private readonly $type$ _value;

    public $class$($type$ value)
    {
        _value = value;
    }
}]]></Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文