- Home /
Error on generic class with generic method.
So I am trying to make a system that has a class that gets a type of node from a looping system. There will be a few types of nodes so I am trying to use a generic pooling class, but the problem is to have a dictionary of these generic poolers I had to make an interface that has a generic method, but isn't generic itself. So the class passed to the generic class will always be the same as the class passed to the method, but I am getting the error "error CS0029: Cannot implicitly convert type 'CommandNode' to 'CommandNode'"
using System;
using System.Collections.Generic;
using StarProductions.Interactables;
public class CommandNodeAbstractPooler
{
private Dictionary<Type, ICommandNodePooler> _commandNodePoolers;
/// <summary>
/// Gets a node that uses the TYPE of InteractableMonoBase.
/// </summary>
/// <typeparam name="TYPE">The type of node to return.</typeparam>
/// <param name="target">The interactable to make the node from.</param>
/// <returns>The node that holds the command values.</returns>
public CommandNode<NODE_TYPE> GetCommandNode<NODE_TYPE>(InteractableMonoBase target) where NODE_TYPE : CommandNode<NODE_TYPE>
{
var type = typeof(NODE_TYPE);
if (_commandNodePoolers.ContainsKey(type))
return _commandNodePoolers[type].GetCommandNode<NODE_TYPE>(target);
_commandNodePoolers.Add(type, new CommandNodePooler<NODE_TYPE>());
return _commandNodePoolers[type].GetCommandNode<NODE_TYPE>(target);
}
}
public interface ICommandNodePooler
{
CommandNode<NODE_TYPE> GetCommandNode<NODE_TYPE>(InteractableMonoBase command/*, CommandNodeBuilder nodeBuilder*/) where NODE_TYPE : CommandNode<NODE_TYPE>;
}
public class CommandNodePooler<NODE_TYPE2> : ICommandNodePooler where NODE_TYPE2 : CommandNode<NODE_TYPE2>
{
private CommandNode<NODE_TYPE2> CommandsEnd;
public CommandNode<NODE_TYPE> GetCommandNode<NODE_TYPE>(InteractableMonoBase command/*, CommandNodeBuilder nodeBuilder*/) where NODE_TYPE : CommandNode<NODE_TYPE>
{
if (CommandsEnd != null)
{
var holder = CommandsEnd;
CommandsEnd = CommandsEnd.Last;
if (holder is CommandNode<NODE_TYPE2>)
// Error here.
return holder;
}
return null;
}
}
public abstract class CommandNode<TYPE>
{
public TYPE Last;
public TYPE Next;
}
Answer by Bunny83 · Mar 23, 2019 at 01:36 AM
Your abstract CommandNode class has no constraint on the generic type argument. So the compiler can't make any assumption on the type. Keep in mind that generic code need to work at compile time with all possible type arguments that are within the set constraints.
Note that you're mixing generic types here. Many don't really understand that generic types are not a way to unify classes but to seperate them, making them distinct from each other. A List<int>
and a List<string>
are two complete different classes. There is no way to convert a CommandNode<NODE_TYPE2>
into a CommandNode<NODE_TYPE>
as they are two complete seperate things. If you create a class A and a class B like this:
public class A : CommandNode<A>{}
public class B : CommandNode<B>{}
Those two classes have nothing in common and can not be converted into each other. Generics are there to share common functionality but from an inheritance point of view they are completely seperate. So you can not have valid generic code that does this. It is possible to convert it if you're casting over System.Object like this:
return (CommandNode<NODE_TYPE>)((object)holder);
Note that your type check it completely pointless. Your variable "CommandsEnd" and "holder" are both declared as CommandNode<NODE_TYPE2>
, so a check if holder is of type CommandNode<NODE_TYPE2>
will always be true. Maybe you wanted to check against CommandNode<NODE_TYPE>
?
Your answer
Follow this Question
Related Questions
Serialization of generic abstract class 1 Answer
Grabbing an object from array 0 Answers
Check if GameObjects are from the same prefab? 1 Answer
hel with object pooling? 2 Answers
In need of some help with objectpooling and randomised tag setting 0 Answers