- Home /
Delegate Covariance and Contravariance using .NET 4.x Equivalent
According to this post by Microsoft the block of code below should work, but won't even compile in Unity. Does Unity not support this, despite it being introduced in C# 4.0?
public class StartData : EventData
{
public float Time;
}
public class TestClass : MonoBehaviour
{
System.Action<EventData> _handler = null;
private void Start()
{
_handler += TestCallback;
}
private void TestCallback(StartData startData)
{
Debug.Log("Testing");
}
}
Answer by Bunny83 · Aug 20, 2018 at 03:19 AM
No this doesn't work. You got the thing the other way round. The delegate has to have the more concrete parameter type while the actual handler hooked up can have a more abstract parameter type. So it would be save for the delegate to pass a "StartData" instance while the delegate receives an "EventData" instance. Since StartData is derived from EventData this works. However it doesn't work the other way round. Imagine you have another class like this:
public class SomeOtherData : EventData
{
public float FooBar;
}
Since your delegate parameter type is EventData it would be perfectly fine to pass a SomeOtherData instance to the delegate:
_handler(new SomeOtherData());
However you can not hook up a method with a more concrete parameter type as "SomeOtherData" can't be casted to "StartData".
Contravariance applies to parameters while Covariance applies to return types. The return type acts the other way round since the data flow is in the opposite direction. So the delegate can return an abstract / base data type while the actual handler hooked up can return a derived class, but not the other way round.
Just keep the data flow in $$anonymous$$d. Up-casting is always allowed (casting to a less derived type / base class) while implicit down casting is not allowed. So if a method expects a "Dog" you can not pass an "Animal" or anything else derived from Animal beside a Dog. However if the method expects an Animal you can pass a Dog, a Cat or anything derived from Animal. The passing along the parameter from the delegate to the hooked up method has to follow the same rules.
Actual instance
passed as
parameter
|
\|/
delegate
| // The parameters of the delegate type has to be
\|/ // more concrete or the same as those of "method"
method
| // the return type of method has to be more concrete
\|/ // or the same as the delegate return type
delegate
return type
|
\|/
Note: Don't confuse delegate co- / contravariance with generic co- / contravariance which was introduced in .NET 4. delegate co- / contravariance was supported since .NET 2.0 and array covariance since .NET 1.0 as you can read here
Answer by Trevdevs · Aug 20, 2018 at 01:46 AM
Make sure this is set unity doesn't have it set to 4.x by default
Your answer
Follow this Question
Related Questions
Action contravarience issue, throwing ArgumentException: Incompatible Delegate Types 1 Answer
No Option to Select .NET 4.x API Compatibility 1 Answer
my Monodevelop can't code, any help or solution? 2 Answers
Unity .net framework 4.5 1 Answer
Script FPS Game Emitter Compiler error,ParticleEmitter now wont work 0 Answers