Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

circular generic type parameters

Tags:

I have 2 generic classes, a BaseComponent Class, and a BaseManager class.

They're both abstract and are intended to be made concrete.

public abstract class BaseManager<T> where T : BaseComponent<?>
public abstract class BaseComponent<T> where T : BaseManager<?>

BaseManager has a list of BaseComponents, which is why i want to make it generic, so a PhysicsManager : BaseManager<PhysicsComponent> would have a list of PhysicsComponents.

I want (or rather, think i need) BaseComponent to be generic because i only ever want classes derived from BaseComponent to be 'attached' to their appropriate manager. Ideally i don't want to have to write a constructor per derived component just so i can add it to a passed in concrete manager class. Ideally i want to have a constructor that takes the abstract BaseManager class.

How can i manage this kind of circular dependency?

like image 525
George Duckett Avatar asked Nov 15 '11 15:11

George Duckett


People also ask

What are generic type parameters?

Generic Type Parameters (C# Programming Guide) In a generic type or method definition, a type parameters is a placeholder for a specific type that a client specifies when they instantiate a variable of the generic type.

What is a type parameter in Java?

In a generic type or method definition, a type parameter is a placeholder for a specific type that a client specifies when they create an instance of the generic type. A generic class, such as GenericList<T> listed in Introduction to Generics, cannot be used as-is because it is not really a type; it is more like a blueprint for a type.

Why can't a generic class be used as-is?

A generic class, such as GenericList<T> listed in Introduction to Generics, cannot be used as-is because it is not really a type; it is more like a blueprint for a type. To use GenericList<T>, client code must declare and instantiate a constructed type by specifying a type argument inside the angle brackets.

How do I use genericlist<T> in Java?

To use GenericList<T>, client code must declare and instantiate a constructed type by specifying a type argument inside the angle brackets. The type argument for this particular class can be any type recognized by the compiler. Any number of constructed type instances can be created, each one using a different type argument, as follows:


1 Answers

It sounds like you might want to have two generic type parameters:

public abstract class BaseManager<TComponent, TManager>
    where TComponent : BaseComponent<TComponent, TManager>
    where TManager : BaseManager<TComponent, TManager>
public abstract class BaseComponent<TComponent, TManager>
    where TComponent : BaseComponent<TComponent, TManager>
    where TManager : BaseManager<TComponent, TManager>

Yes, it's smelly - but that's the sort of thing I've done in Protocol Buffers.

So then you'd have:

public class PhysicsManager : BaseManager<PhysicsComponent, PhysicsManager>

public class PhysicsComponent : BaseComponent<PhysicsComponent, PhysicsManager>
like image 104
Jon Skeet Avatar answered Oct 04 '22 06:10

Jon Skeet