编码C#时,我经常发现自己实现了不可变类型。 我总是写完了很多代码,我想知道是否有更快的方法来实现它。
我通常写的是:
public struct MyType
{
private Int32 _value;
public Int32 Value { get { return _value;} }
public MyType(Int32 val)
{
_value = val;
}
}
MyType alpha = new MyType(42);
当字段数量增加并且输入很多时,这变得相当复杂。 有没有更有效的方法来做到这一点?
答案 0 :(得分:5)
我建议编写更少代码的唯一方法是使用类似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没有为此模式生成代码,因此您仍然需要手动构建(大部分)它。
答案 1 :(得分:4)
您可以使用自动属性和私有设置器简化它,如下所示:
public struct MyType
{
public Int32 Value { get; private set; }
public MyType(Int32 val)
{
Value = val;
}
}
答案 2 :(得分:1)
救援时的代码片段! 将此xml保存为“immutable.snippet”,然后转到Visual Studio,选择Tools,Code Snippets Manager并导入它。而已!现在编写“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>