在C#中,有没有一种优雅的方法为属性设置默认值?

5

我在SO上读到了使用属性而不是字段的好处,所以现在我想将我的代码从使用字段转换为使用属性。

对于类的实例字段,我可以设置默认值。例如:

int speed = 100;

对于等效属性,我认为应该是:

int Speed { get; set; }

我的理解是,当实例化一个类时,Speed属性会被初始化为零。但我无法找到如何设置默认值以便轻松更新我的代码。是否有一种优雅的方式来为属性提供默认值?
看起来应该有一种优雅的方法来做到这一点,而不需要使用构造函数,但我却找不到如何做。

使用构造函数有什么问题?或者手动定义支持字段而不是自动属性的属性有什么问题? - Anon.
如果我可以在先前声明字段的同一位置将该字段更改为属性,那么我的转换任务将变得更加容易。如果使用构造函数,则需要滚动代码以进行更改。我不知道您可以使用已初始化的后备字段。 - Jeremy Larter
1
C# 6的新特性:自动属性初始化器。 - Joe Enos
6个回答

7

最好的方法是使用普通的、老式的字段支持属性,例如:

private int _speed = 100;
public int Speed { get { return _speed; } set { _speed = value; } }

谢谢你的代码。非常优雅,我不需要使用构造函数。太棒了。 - Jeremy Larter
没问题。这是在.NET 3.0之前编写的代码中经常看到的情况。随着3.0的推出,自动属性被引入,但正如你提出的问题一样,你无法简单地定义默认值,而不使用构造函数。 - Joe Enos
我仍然喜欢旧的属性设置方式,但是这可能会导致混淆,因为你不知道在类内部应该使用哪种方式来获取/设置值。你是使用实例变量还是使用属性? - Jerod Houghtelling
@Jerod:如果您使用诸如NCover之类的代码分析工具,它将捕获属性访问器,而不是字段赋值。也许这会稍微慢一些?可能不会注意到。如果您想要进行任何输入验证或其他廉价功能例程时获取/设置属性,则绝对需要使用属性。有时我使用一个支持两个或更多属性的字段,但在其中一个上使用类型转换。例如,一个List<string>的私有字段和一个用于获取/设置String[]的属性,但我也可以使用获取/设置以获取CSV的String - maxwellb
@maxwellb:你提到在访问属性时进行输入验证或类似操作时使用属性,我认为这是始终使用属性的好理由。如果你大多数时间都习惯于使用字段,那么在有合法理由时可能会忘记使用属性。如果你习惯于使用属性,那么你永远不会错过重要的调用。 - Joe Enos

6

我认为设置默认值最简单的方法是:

public sealed class Employee
{
    public int Id { get; set; } = 10;
}

当最初提出这个问题时,这个选项还没有可用,但现在它是一个很好的选择!应该被接受为答案。 - CarCar

2
我使用的设计模式在微软的Windows.Forms控件和其他.NET类中广泛使用。此外,据我理解,构造函数之外的初始化允许即时编译器优化类代码。
public class Foo {
    public static const int DefaultSpeed = 100;
    private int _speed = DefaultSpeed;
    [DefaultValue(DefaultSpeed)]
    public int Speed { get { return _speed; } set { _speed = value; } }
}

    public class Foo {
        public static Color DefaultForecolor { get {return SystemColors.WindowText; }}
        private Color _forecolor = DefaultForecolor;
        [DefaultValue(DefaultForeColor)]
        public Color Forecolor { get { return _forecolor; } set { _forecolor = value; } }
    }

1

你必须在构造函数中设置属性的默认值。对于自动属性,除此之外没有其他方法可以做到这一点,因为自动属性的字段是在编译时声明并在getter/setter中替换的。但是对于显式属性,你可以像Joe在他的答案中提到的那样初始化属性使用的字段以进行读取或写入。


1
构造函数是设置自动属性初始值的唯一方式。

1

CciSharp 支持 DefaultValue 属性,可以将默认值放置在自动属性上。然而,CciSharp 是否符合 "优雅" 的解决方案,则取决于个人观点(它作为编辑二进制文件中的 IL 的后编译器)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接