I want to use Generic type definitions in the Unity Editor and cannot (yet) update to Unity 2020.1 which natively supports this. The workaround is to define a non-generic class that extends the generic class. However, when I try to override a base class property, with a defined class which is basically a named version of the generic property, the compiler reports both types to be incompatible. Since this description is quite ... generic ... here is some code to illustrate my issue:
class Property<T> { }
class BaseClass<T>
{
public virtual Property<T> Property { protected get; set; }
}
class StringProperty : Property<string> { }
class SubClass : BaseClass<string>
{
public override StringProperty Property { protected get; set; }
}
SubClass.Property': type must be 'Property<string>' to match overridden member 'BaseClass<string>.Property
SubClass.Property is basically Property<string> but I don't know how to communicate this to the compiler.
The issue is that while every StringProperty is a Property<string>, not every Property<string> is a StringProperty. Sounds weird? So here we go.
Imagine a client of your class has this:
BaseClass<string> b = new SubClass();
Now one would assume that we can do this:
b.Property = new MyProperty();
where MyProperty also derives from Property<string>. However this contradicts your expectation that instances of SubClass have a StringProperty, not a MyProperty.
That has nothing to do with generics. In short you cannot change the signature of a member by overriding it. Both the base-class- and the derived-class-member have to have the exact same signature, including the return-type.
Covariant return types are not supported. I believe it is added with C# 9.
It means that you can not change the return type of the overridden method. Even if the overridden method returns a derived type.
Something like this is not valid:
class Animal
{
}
class Cat : Animal
{
}
abstract class AnimalFactory
{
public abstract Animal CreateAnimal();
}
class CatFactory : AnimalFactory
{
public override Cat CreateAnimal(); // Syntax error
}
Although we are returning an Animal (a Cat is an Animal), it will give a compiler error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With