Do i really have to copy all constructors from Foo into Bar and Bah? And then if i change a constructor signature in Foo, do i have to update it in Bar and Bah?
Yes, if you use constructors to create instances.
Is there no way to inherit constructors?
Nope.
Is there no way to encourage code reuse?
Well, I won't get into whether inheriting constructors would be a good or bad thing and whether it would encourage code reuse, since we don't have them and we're not going to get them. :-)
But here in 2014, with the current C#, you can get something very much like inherited constructors by using a generic create method instead. It can be a useful tool to have in your belt, but you wouldn't reach for it lightly. I reached for it recently when faced with needing to pass something into the constructor of a base type used in a couple of hundred derived classes (until recently, the base didn't need any arguments, and so the default constructor was fine — the derived classes didn't declare constructors at all, and got the automatically-supplied one).
It looks like this:
// In Foo:
public T create<T>(int i) where: where T : Foo, new() {
T obj = new T();
// Do whatever you would do with `i` in `Foo(i)` here, for instance,
// if you save it as a data member; `obj.dataMember = i;`
return obj;
}
That says that you can call the generic create function using a type parameter which is any subtype of Foo that has a zero-arguments constructor.
Then, instead of doing Bar b new Bar(42), you'd do this:
var b = Foo.create<Bar>(42);
// or
Bar b = Foo.create<Bar>(42);
// or
var b = Bar.create<Bar>(42); // But you still need the <Bar> bit
// or
Bar b = Bar.create<Bar>(42);
There I've shown the create method being on Foo directly, but of course it could be in a factory class of some sort, if the information it's setting up can be set by that factory class.
Just for clarity: The name create isn't important, it could be makeThingy or whatever else you like.
Full Example
using System.IO;
using System;
class Program
{
static void Main()
{
Bar b1 = Foo.create<Bar>(42);
b1.ShowDataMember("b1");
Bar b2 = Bar.create<Bar>(43); // Just to show `Foo.create` vs. `Bar.create` doesn't matter
b2.ShowDataMember("b2");
}
class Foo
{
public int DataMember { get; private set; }
public static T create<T>(int i) where T: Foo, new()
{
T obj = new T();
obj.DataMember = i;
return obj;
}
}
class Bar : Foo
{
public void ShowDataMember(string prefix)
{
Console.WriteLine(prefix + ".DataMember = " + this.DataMember);
}
}
}