Skip to content

[FEATURE] Support types with contravariance #70

@DreadKyller

Description

@DreadKyller

Feature destription

Given a structure like the following:

interface IAction<in T> where T : IActor { ... }

interface IActorAction : IAction<IActor> { }
interface IStandardActorAction: IAction<IStandardActor> { }
interface INetworkActorAction: IAction<INetworkActor> { }

Where IStandardActor and INetworkActor have a shared super interface of IActor.

We can imagine the situation where IActor is used for actions that are compatible with both standard and networked actors, where IStandardAction and INetworkAction are only compatible with IStandardActor and INetworkActor respectively, where IStandardActor may be implemented on a MonoBehaviour and INetworkActor may be implemented on a NetworkBehaviour.

Under such conditions, attempting to store the list of actions as such:

[SerializeReference, SubclassSelector]
private List<IAction<INetworkActor>> actions;

That list of actions should allow selection of both IAction<INetworkActor> and IAction<IActor>, as IAction<IActor> is contravariant to IAction<INetworkActor> and IAction::T is marked as supporting contravariance. In fact if I manually add an implementation of both to the list it is fully supported, but only IAction<INetworkActor> specifically are found with the subclass selector.

This scenario is what we find ourselves dealing with when working on a modular controller for our games. Supporting contravariant types like this would, I feel, be quite useful.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions