3

In C# you have object initializers to initialize fields of objects at creation time without using a constructor.

Now I'm wondering if there is an equivalent to classes which means that you can 'initialize' properties of classes when defining subclasses without actually using an override syntax but simply declaring what the value of a known property is.

Example:

public abstract class Car {
    public abstract string Name { get; }
}
// usual approach
public class Mustang : Car {
    public overwrite string Name { get { return "Ford Mustang"; } }
}
// my idea of avoiding boilerplate code
public class Mustang : Car { Name = "Ford Mustang" }

Is there a way to accomplish this? If there is none, could T4 templates be of any help?

Bastian
  • 4,638
  • 6
  • 36
  • 55

2 Answers2

6

To make rekire's example clearer, you'd write something like:

public abstract class Car
{
    public string Name { get; private set; }

    protected Car(string name)
    {
        this.Name = name;
    }
}

public class Mustang : Car
{
    public Mustang() : base("Mustang")
    {
    }
}

EDIT: Another option is to use attributes, where you'd write:

[CarName("Mustang")]
public class Mustang : Car

... having written appropriate reflection code in Car. I would strongly recommend that you don't though. Of course, attributes may be useful in your real context.

Moog
  • 10,193
  • 2
  • 40
  • 66
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Nice example, it's hard to write such an example on a mobile device. – rekire Nov 24 '12 at 10:17
  • Well that would also do the job, but I would like to abbreviate the amount of code even further if possible (that is why I came up with T4 templates). – Bastian Nov 24 '12 at 10:18
  • @Bastian: Are properties like this really taking a significant amount of your code? If so, that suggests a redesign may be in order. If you just want to reduce the number of *lines*, you could always put the whole of the `Mustang` constructor on one line. Or you could perhaps use attributes. – Jon Skeet Nov 24 '12 at 10:22
  • @JonSkeet I just like to keep it concise (as far as readability is not impaired). About the attributes approach: Visually it points to the right direction but due to performance reasons I definitely don't want to use reflection at runtime. – Bastian Nov 24 '12 at 10:33
  • @JonSkeet Another question though: Would the constructor approach be as performant as the overwriting approach (as the property configuration would happen at runtime)? – Bastian Nov 24 '12 at 10:40
  • @Bastian: Assuming the property will actually be used, I'd expect it to be more efficient in terms of *time* as it avoids a virtual invocation (the property access can just be inlined) - but it does mean having an extra field per object, so it'll take a little bit more memory. – Jon Skeet Nov 24 '12 at 10:57
1

You could do this via a construtor, where you need to call the base class constructor.

class car {
    Public string Name {public get; protected set}
}

That should basically work too.

rekire
  • 47,260
  • 30
  • 167
  • 264
  • I prefer the constructor version, however - it means you can guarantee that the name will never change after construction. – Jon Skeet Nov 24 '12 at 10:15