UPDATE:
Thanks to some help it seems to be a bug with Unity's compiler as it doesn't happen outside of Unity. I am currently submitting a bug report and I'll try and find a work around.
I originally posted this to reddit but I think I will need all the help I can get. Here is it copied over:
Not sure how it has come to this, but in order to maintain maximum extendability I have had to use all this techniques. In short, this works
ICombatEffect<IEffectReturn> com = new TackleEffectBase(this);
but when I try this
ICombatEffect<IEffectReturn>[] EffectsArra = ICombatEffect<IEffectReturn>[]{new TackleEffectBase(this);}
or this
List< ICombatEffect<IEffectReturn>> EffectsList = new List< ICombatEffect<IEffectReturn>>{new TackleEffectBase(this)}
I get an ArrayTypeMismatchException.
Now for the details: (although I've condensed this a lot) p
ublic interface ICombatEffect<out T> where T : IEffectReturn
{
T Effect(CombatProcessor combat);
}
public abstract class EffectTemplate<T1> : ICombatEffect<T1> where T1 : IEffectReturn
{
public abstract T1 Effect(CombatProcessor combat);
}
public abstract class DamageBaseTemplate : EffectTemplate<DamageBaseModifier>
{}
DamageBaseModifier : IEffectReturn
public class TackleEffectBase : DamageBaseTemplate
I've left out all of the functional stuff so I can let the types do the talking. The premise is that I each ICombatEffect has an Effect Method. The Effect method must always have a return type that implements IEffectReturn interface. I need to preserve the return type of each ICombatEffect as it is used for sorting later.
Since I have quite a lot of functional code, I've put in the abstract class EffectTemplate. I've read a lot about this sort of style and the trick is to make the interface non-generic. I do not have that luxury unfortunately as sometimes I will not be using the template. So I have set up the interface with a covariant generic type. The abstract class sort of has its generic type linked so they will be the same. This took me a bloody long time to figure out and I was pretty disappointing when I couldn't get it to run today.
I'm no expert on generics but here is my theory on why I can create a single instance but not add that to a collection. When you declare the single instance it goes through and sets all the generics to the instance's type. For a collection, you can't really make its generics concrete, they are only there to see if it slots in.
I'm pretty ok with tearing this down for a better solution as long as it fulfills my needs, but I'm pretty darn curious about this solution. I thought myself so clever when I got all these cascading generic types to work, but alas.