Unity says I need to be able to convert a type to a type to use it as generic, but it is

Updated on September 12, 2016 in Answers
Share on Facebook0Tweet about this on TwitterShare on Google+0Share on Reddit0
4 on September 10, 2016

Was a little hard to make the title, and I am not proud of it…I am just not able to think of a better one, sorry.

I have an RPG game where I separated the stats and general components. That means, a player will have both a PlayerStats and a Player component, instead of putting the PlayerStats in the player.
I have an interface called “IStatsBase”, which contains stuff that are not related to generic types (hp, speed, etc.). Then for every type of character I will have another base interface, so let’s take the player, for instance, it will have an interface called “IPlayerStatsBase”, and that will inherit from IStatsBase and contain some more things that don’t need generic types.
Now I have a separated, yet related, interface inheritance chain. It starts with IStats, which is generic interface that contains things that are stats related and do need type parameters. Such as a reference to the main player component. Then I will have a derived one called “IPlayerStats”, which will derive from both IStats and IPlayerStatsBase. This is the interface every player stats class should derive from, and of course, input a type argument. Then I will make a class which will implement that interface. Let’s say we have a player called “Stan”, so we will have a component called “StanStats” that will both derive from MonoBehaviour and implement IPlayerStats.

Now for a different one. The one for the character. I have an abstract class called “CharacterBehaviourBase” which has everything a character needs that does not require type parameters. So name, level, etc.. Then I have a generic one (“CharacterBehaviour”) that derives from CharacterBehaviourBase. Then a base class for all character types, let’s say player, so Player will derive from the generic CharacterBehaviour. Then every specific character (Stan is our example) will have a class, so a class/component called “Stan”, that will derive from Player.

The generic type IPlayerStats will take is a type that must derive from Player. The type parameter Player takes must implement IPlayerStatsBase.

So here is the error I got (of course with “Stan”, which is not the name I used, oh, and I don’t know how to paste an error, so I just pasted it as italic text):
The type `Stan’ must be convertible to `Player’ in order to use it as parameter `T’ in the generic type or method `IPlayerStats’

Just know that I got the error in StanStats, where I use Stan as the type argument to IPlayerStats when I inherit from itSo Stan must be convertible to Player, right? So let’s check if it is.
Stan derived from Player.
So it does derive from Player, but I can’t be sure it’s Player. So let’s check what is that “StanStats” class.
StanStats derives from MonoBehaviour, and it implements IPlayerStats. So still not IPlayerStatsBase, but maybe it will be. Let’s check IPlayerStats.
IPlayerStats derives from…you guessed it… IPlayerStatsBase (and IStats, but it doesn’t matter).

So my conclusion is that “Stan” is indeed convertible to “Player”, and this error doesn’t make any sense. I might be missing something, something of type “C# is limiting you” (because that’s an answer I got in my last few questions…it makes me want to just use Unreal and C++ :/), but there might be a real thing I can do, so I am asking.

(The question is over, but I do have some things to ramble about, so if you do care about those things, keep on reading.)
Sorry for the long post…for some reason in the last few questions I asked on forums I wasn’t able to make it short, clear, detailed and to-the-point. Let’s hope this one is at least OK, and you are able to understand.

  • Liked by
3 on September 10, 2016

So… I kinda get what you are doing.
The thing is that whenever it takes so long to explain the structure of your program, then it’s probably structured with flaws.
I’ve got some questions for you. Not that I specifically need those answers, but they’re for you to think about.
Do you need all those interfaces? You make interfaces for very specific things. They’re not made for that.

Do the stat types of all the characters need to be different? There’s nothing wrong with unused stats.
Are you sure you are taking the right path? You say you want to make things generic, but you end up making them more abstract.
In general I’ve learnt that having multiple layers of interfaces often doesn’t work out.
The problem is not that C# is limiting you,  I think that you are limiting C# with the amount of interfaces 😉

on September 11, 2016

Yes, I know, it was a joke when I said C# is limiting me, it was because of something completely different. 😉

The reason I separated the generic interfaces and the non-generic interfaces is because if I wanted to reference them in generic constraints of other classes I would have to specify the generic type, which I can’t, that’s why I must separate it.

The reason I didn’t just make a “PlayerStats” class is to “future proof”. You maybe are right, and I will end up just making a stats class for all players, or any other kind of player. Though that doesn’t solve my problem.

I think I am taking the right path. I might not do this correctly, but the idea is there, and I think if I will succeed implementing it it will be much better than not using base classes, interfaces and generics.

on September 11, 2016

Ok, I thought about it, and I want to fix my answer a little bit… I said I might make a PlayerStats class, but now i decided to make it.
There won’t be any specific interface for a player, or an enemy. There also won’t be a specific interface for the references, or the things that don’t require type parameters. Actually, there won’t be any type parameters, or references. The classes can implement it themselves.
If I will want to add specific functionality to the stats, I could just inherit from the PlayerStats class, so it’s perfect.

It theoretically should fix my problem, but I can’t try it now. I will update that thread when I will have the answer.

on September 12, 2016

Ok, it worked (though now I got another problem, but it has nothing to with this thread).
But I did get a problem that is related. I can’t add a solved mark in the title because I already reached the letters limit.

Show more replies
  • Liked by