Multiple inheritance isn't supported in C#, for good but boring reasons that I won't go into in this answer.
The correct way to do this is to make an interface for each set of functionality that is separately required, like you said. You're right that this requires some boilerplate code, but traditional way of doing what you're asking, if the required functionality is simple (like just adding a property). It allows you to specify what classes have what properties, without creating a messy class hierarchy.
So something like this:
public interface IHasName
{
public string Name { get; set; }
}
public interface IHasAddress
{
public string Address { get; set; }
}
public class HasAName : IHasName
{
public string Name { get; set; }
}
public class HasAddress : IHasAddress
{
public string Address { get; set; }
}
public class HasANameAndAddress : IHasName, IHasAddress
{
public string Name { get; set; }
public string Address { get; set; }
}
You said you have concerns about implementing every property on every class, but it is the recommended way of getting around multiple-inheritance related situations.
You can of course go down the composition route instead which is a good move for more complex scenarios, but for this simple scenario it will create more bloat classes and more setup/boilerplate for each property.
That being said...
The properly implemented interfaces are the right way to go here, but I'm going to present a hacky way of avoiding the boilerplate, if you feel you really need to.
If you really really want to avoid boilerplate, you can abuse Extension methods and Interfaces so that you can simulate arbitrary properties on interfaces without actually including them in the interface, like so:
public interface IHasName { }
public static class Extensions
{
public static Dictionary<IHasName, string> nameLookup = new Dictionary<IHasName, string>();
public static string GetName(this IHasName obj)
{
if(nameLookup.TryGetValue(obj, out var name))
{
return name;
}
return null;
}
public static void SetName(this IHasName obj, string name)
{
nameLookup[obj] = name;
}
}
Here, there's an interface called IHasName
, but it doesn't actually contain a string Name
property on it, it's just empty. We then create an Extensions class that has a backing Dictionary
that stores a name value in that instead, and Get/Set methods to read/write to that dictionary.
So from here, you can do this:
public class SomeClassWithAName : IHasName
{
}
And read/write it's name property like this:
var a = new SomeClassWithAName();
a.SetName("Greg");
Console.WriteLine(a.GetName());
From here you could extend this to add a IHasAddress
interface and another group of get/set address extension methods with another backing dictionary. This would mean you could then do this:
public class SomeClassWithANameAndAddress : IHasName, IHasAddress
{
}
And set up your classes by just attaching the relevant interfaces without having to add boilerplate properties to every class.
Note again: this is slightly hacky way around your issue of trying to reduce repeated code. If it's not suitable, use standard interfaces or composition.