yellowblood
yellowblood

Reputation: 1631

C# Lack of Static Inheritance - What Should I Do?

Alright, so as you probably know, static inheritance is impossible in C#. I understand that, however I'm stuck with the development of my program.

I will try to make it as simple as possible. Lets say our code needs to manage objects that are presenting aircrafts in some airport. The requirements are as follows:

So, basically, if I could enforce inherited classes to implement static members and methods, I would enforce the aircraft types to have static members such as FriendlyName. Sadly I cannot do that.

So, what would be the best design for this scenario?

Upvotes: 7

Views: 401

Answers (7)

Jordão
Jordão

Reputation: 56537

An interesting way to solve this problem is to recognize that aircraft types are also an important concept in the design and create them as separate classes, whose instances act as types of aircrafts. This is known as the type object pattern (pdf), and it allows for very flexible designs.

Upvotes: 0

Jonathon Reinhart
Jonathon Reinhart

Reputation: 137547

@Aaronaught hit the nail on the head with the plugin-like architecture comment.

What I did the last time I encountered this, was to have a "Descriptor" type that was not terribly expensive to create, and keep the meta data in an instance field.

public class F16Descriptor : AircraftDescriptor
{
    public override string Name { get { return "Lockheed Martin F-16 Fighting Falcon"; } }
    public override Type AircraftType { get { return typeof(F16); } }
}

public class F16 : AircraftBase
{
    ...
}

Upvotes: 0

Dan Bryant
Dan Bryant

Reputation: 27515

This is a case where you may benefit from a Factory pattern. Instead of importing specific types of Aircraft, provide a standard IAircraftFactory interface that defines what every Aircraft Factory needs to do for you. This is where you can return descriptions, UI information, etc. The Aircraft Factory is then responsible for creating the particular Aircraft. Because your clients must create a custom Factory in order to expose their Aircraft, they are forced to implement the interface and reminded (via its members) that they have a contract to fulfill.

Something like:

public interface IAircraft
{
    //Aircraft instance details...
}

public interface IAircraftFactory
{
    //Can include parameters if needed...
    IAircraft BuildAircraft();

    //And other useful meta-data...
    string GetDescription();
}

//In some other Client-provided DLL...
public class MyAircraftFactory : IAircraftFactory
{
    IAircraft BuildAircraft()
    {
        return new MyAircraft();
    }

    //...
}

Upvotes: 2

Fitzchak Yitzchaki
Fitzchak Yitzchaki

Reputation: 9163

Don't use static methods. use instance methods instead.

Also the top abstract may expose an abstract method that will return the aircraft specific name.

public abstract class Aircraft
{
    public abstract string Name { get; }
    public abstract string FriendlyName { get; }
}

Upvotes: 3

Dustman
Dustman

Reputation: 5261

Use an enumeration for the friendly names, and create an instance member of that type for the friendly name. Require the initialization of this member during construction.

Upvotes: 1

3Dave
3Dave

Reputation: 29081

Why do you need these properties to be static?

public class Aircraft
{
protected string AircraftName { get; protected set; }
}

public class F16 : Aircraft
{
   public F16()
   {
     AircraftName="F16 Falcon";
   }
}

Upvotes: 4

Aaronaught
Aaronaught

Reputation: 122684

One answer is to decorate each class with attributes (metadata):

[Description("Lockheed Martin F-16 Fighting Falcon")]
public class F16 : Aircraft
{
    // ...
}

This is using the DescriptionAttribute already in System.ComponentModel.

You can get the metadata like this:

Type t = typeof(F16);
DescriptionAttribute attr = (DescriptionAttribute)Attribute.GetCustomAttribute(t,
    typeof(DescriptionAttribute));
string description = (attr != null) ? attr.Description : t.Name;

This will get you the description text from a reference to the F16 class.

Upvotes: 8

Related Questions