Как эффективно реализовать неизменяемые типы - PullRequest
5 голосов
/ 30 августа 2011

При кодировании C # я часто реализую неизменяемые типы. Я всегда заканчиваю тем, что пишу довольно много кода, и мне интересно, есть ли более быстрый способ достичь этого.

Что я обычно пишу:

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

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

MyType alpha = new MyType(42);

Это становится довольно сложным, когда количество полей увеличивается, и много набирается. Есть ли более эффективный способ сделать это?

Ответы [ 3 ]

5 голосов
/ 30 августа 2011

Единственный способ, которым я могу предложить написать меньше кода, - это использовать что-то вроде 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 нет генерации кода для этого шаблона, поэтому вам все равно придется создавать (большую часть) его вручную.

4 голосов
/ 30 августа 2011

Вы можете немного упростить это с помощью автоматических свойств и частного сеттера, как показано ниже:

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

  public MyType(Int32 val)
  {
     Value = val;
  }
}
1 голос
/ 30 августа 2011

Кодовые фрагменты на помощь! Сохраните этот XML-файл как «immutable.snippet», затем перейдите в Visual Studio, выберите «Инструменты», «Диспетчер фрагментов кода» и импортируйте его. Это оно! Теперь напишите «неизменный» и дважды нажмите 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>/5666150/kak-effektivno-realizovat-neizmenyaemye-tipy</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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...