views:

83

answers:

7

Data class, in this question scope, is a class with more public properties than methods.

Should I:

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

Or:

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;
    }
}
+3  A: 

With the new object initialization available in C# 3.0 I do not see the need for trivial constructors anymore. Unless you need to do some custom initialization logic I would not add it.

in your case you could use the first class definition and perform initialization like that:

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

Here you can find an example of how to use the "new" object initialization: http://www.developer.com/net/csharp/article.php/3605011/One-Step-Object-Creation-and-Initialization-in-C-30.htm

Manu
Yes, I am aware of that, and this question was made with that in mind. Thanks for your opnion ("I do not see the need for trivial constructors").
Jader Dias
+3  A: 

I think that really depends on whether or not you need those values to be initialized. You can't depend on the Real and Imaginary values being set without explicitly forcing them to be set in the constructor. Technically, someone could set them to some arbitrary value in the constructor which could cause problems, but by forcing them to be set in the constructor you are essentially saying "Hey! These values are important to the object."

Kevin
I agree with you.
Jader Dias
A: 

Well, in the case of a complex number, I would argue that it should be an immutable struct, rather than a class with setters. Therefore, it will need to initialize its values in the constructor.

If, however, you're talking about representing something that should be a mutable class, then it doesn't really matter as much. My preference would be to create a constructor, so that it's easily discoverable which fields need to be set to initialize the object.

bdukes
+3  A: 

In the case of your example, a complex number, I would make it an immutable struct instead:

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;
    }
}

More generally, I would say that if certain properties are required in order for the object to be considered valid then have a constructor that takes those values and sets the appropriate properties.

LukeH
+1  A: 

If you have a pure data class I would prefer builder patterns to construct them. Some other class of function that gathers the important data and then generates a sound new object.

But if you use public mutable properties this maybe overkill because every part of the program could change the object without a mechanism to ensure that the object is sound after the change.

Therefor most important thing for you is to ensure that the initialization code isn't duplicated through your whole program.

Janusz
A: 

Both. Or, it depends.

Writing less code is always a good thing, so relying on the default constructor is a fine idea. However, also think of the places where you'll use the class. Which of these seems easier?

  1. Complex c = new Complex { Real = 1d, Imaginary = 0.5 };
  2. Complex c = new Complex(1d, 0.5d);

The former is more explicit in that you can easily see which values are which properties, but its also longer to write.

Then there is also the matter of controlling object state. By using properties and a default constructor, you can't really declare mandatory properties. One could argue this isn't necessary for a data object, but depending on exactly how you're going to use it, it could be important.

Personally, I tend to create my data transfer objects (which are hardly objects) with empty constructors to make serialization easy, as well as convenience constructors that I use throughout the code. For for my value objects, I use only explicit constructors with mandatory properties so I can ensure valid state.

Trinition
A: 

Agree with Kevin - it depends. In scenario 1, your design says "you can change these values however you want", in scenario 2, it says "you need to give me some values from the beginning". In scenario 2, I would likely change the design to something like this, otherwise, the constructor doesn't buy you anything:

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;
    }
}
Mathias