Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Property in generic base class with different implementation

I've got an abstract class CommandBase<T, X> that I want to have a property InnerCommand.

But since the InnerCommand might have other types for T and X than the command that contains it, how can I define that?

The abstract class:

public abstract class CommandBase<T, X>
    where T : CommandResultBase
    where X : CommandBase<T, X>
{
    public CommandBase<T, X> InnerCommand { get; set; }
    (...)
}

In the example above InnerCommand will only accept instances that have the same types for T and X, but I need to allow for other types.

An AddOrderitemCommand:

public class AddOrderitemCommand : CommandBase<AddOrderitemResult, AddOrderitemCommand>
{
    (...)
}  

Might contain a WebserviceCommand:

public class GetMenuCommand : CommandBase<GetMenuResult,GetMenuCommand>
{
    (...)
}

Please advise on the syntax for allowing this.

like image 214
Gabriël Avatar asked May 29 '13 08:05

Gabriël


People also ask

Can a generic class be derived from another generic class?

In the same way, you can derive a generic class from another generic class that derived from a generic interface. You may be tempted to derive just any type of class from it. One of the features of generics is that you can create a class that must implement the functionality of a certain abstract class of your choice.

Can a generic class inherit?

An attribute cannot inherit from a generic class, nor can a generic class inherit from an attribute.

Can we inherit generic class in C#?

You cannot inherit a generic type. // class Derived20 : T {}// NO!


2 Answers

You basically have three options:

  1. Use dynamic as the type of that property. Nothing I would do.
  2. Use object as the type of that property. Nothing I would do.
  3. Create a non-generic base class or interface for commands. Make CommandBase<T, X> implement it and use it as the type of the property. That's the way I would go.
like image 186
Daniel Hilgarth Avatar answered Oct 27 '22 10:10

Daniel Hilgarth


If the InnerCommand doesn't relate to the parent T/X, then I would suggest using a non-generic InnerCommand that doesn't advertise the type in the signature. This may mean adding a non-generic base-type (CommandBase) or an interface (ICommandBase). Then you can simply use:

public ICommandBase InnerCommand {get;set;}
// note : CommandBase<T,X> : ICommandBase

or

public CommandBase InnerCommand {get;set;}
// note : CommandBase<T,X> : CommandBase
like image 45
Marc Gravell Avatar answered Oct 27 '22 09:10

Marc Gravell