我应该实现构造函数还是使用默认的数据类?

时间:2009-10-28 13:38:27

标签: .net data-structures constructor

在此问题范围中,数据类是一个具有比方法更多公共属性的类。

我应该:

public class Complex
{
    public double Real { get; set; }
    public double Imaginary { get; set; }
}

或者:

public class Complex
{
    public double Real { get; set; }
    public double Imaginary { get; set; }
    public Complex(double real, double imaginary)
    {
        this.Real = real;
        this.Imaginary = imaginary;
    }
}

7 个答案:

答案 0 :(得分:3)

随着C#3.0中新的对象初始化,我不再需要简单的构造函数了。除非你需要做一些自定义初始化逻辑,否则我不会添加它。

在您的情况下,您可以使用第一个类定义并执行类似的初始化:

var c = new Complex { Imaginary = 1, Real = 2 };

在这里,您可以找到如何使用“新”对象初始化的示例:http://www.developer.com/net/csharp/article.php/3605011/One-Step-Object-Creation-and-Initialization-in-C-30.htm

答案 1 :(得分:3)

我认为这实际上取决于您是否需要初始化这些值。您不能依赖于设置的Real和Imaginary值,而不必明确强制它们在构造函数中设置。从技术上讲,有人可以在构造函数中将它们设置为某个可能导致问题的任意值,但是通过强制它们在构造函数中设置,你实际上是在说“嘿!这些值对于对象很重要。”

答案 2 :(得分:3)

对于你的例子,一个复数,我会把它变成一个不可变的struct

public struct Complex
{
    private readonly double _real;
    public double Real
    {
        get { return _real; }
    }

    private readonly double _imaginary;
    public double Imaginary
    {
        get { return _imaginary; }
    }

    public Complex(double real, double imaginary)
    {
        _real = real;
        _imaginary = imaginary;
    }
}

更一般地说,如果需要某些属性才能使对象被认为是有效的,那么请使用构造函数来获取这些值并设置适当的属性。

答案 3 :(得分:1)

如果你有一个纯数据类,我宁愿使用构建器模式来构造它们。一些其他类函数,它们收集重要数据,然后生成一个合理的新对象。

但是如果使用公共可变属性,这可能有点过分,因为程序的每个部分都可以在没有机制的情况下更改对象,以确保在更改后对象是健全的。

因此,最重要的是确保初始化代码不会在整个程序中重复。

答案 4 :(得分:0)

嗯,在复数的情况下,我认为它应该是一个不可变的struct,而不是一个带有setter的class。因此,它需要在构造函数中初始化其值。

但是,如果你在谈论代表应该是可变的class的东西,那么它并不重要。我的偏好是创建一个构造函数,以便很容易发现需要设置哪些字段来初始化对象。

答案 5 :(得分:0)

两者。或者,这取决于。

编写更少的代码总是一件好事,所以依赖于默认构造函数是个好主意。但是,也要想想你将使用这个课程的地方。哪一个看起来更容易?

  1. Complex c = new Complex { Real = 1d, Imaginary = 0.5 };
  2. Complex c = new Complex(1d, 0.5d);
  3. 前者更明确,因为你可以很容易地看到哪些属性是哪些属性,但写入的时间也更长。

    然后还有控制对象状态的问题。通过使用属性和默认构造函数,您无法真正声明强制属性。有人可能会说这对于数据对象来说不是必需的,但是根据你将如何使用它,它可能很重要。

    就个人而言,我倾向于使用空构造函数创建我的数据传输对象(几乎不是对象)以简化序列化,以及我在整个代码中使用的便捷构造函数。对于我的值对象,我只使用具有必需属性的显式构造函数,因此我可以确保有效状态。

答案 6 :(得分:0)

同意凯文 - 这取决于。在方案1中,您的设计说“您可以根据需要更改这些值”,在方案2中,它表示“您需要从头开始给我一些值”。在方案2中,我可能会将设计更改为类似的设置,否则,构造函数不会为您购买任何东西:

public class Complex
{
    public double Real { get; private set; }
    public double Imaginary { get; private set; }
    public Complex(double real, double imaginary)
    {
        this.Real = real;
        this.Imaginary = imaginary;
    }
}