-
Notifications
You must be signed in to change notification settings - Fork 53
Incorrect override or virtual Method Modifiers
When you need to override a method in Java you add the @Override
annotation:
public class MyBaseClass
{
void doSomething () { ... }
}
public class MyClass : MyBaseClass
{
@Override
void doSomething () { ... }
}
However, this information is used by the Java compiler and then discarded. This means it is not available in the compiled .jar
for the bindings process to copy to C#. The bindings process has a complex algorithm where it attempts to determine if a method should be virtual
or override
, but sometimes it makes mistakes.
This can lead to instances like trying to override
an interface
method instead of declaring it as virtual
:
public interface ICloneable
{
Java.Lang.Object Clone ();
}
public class MyClass : Java.Lang.Object, ICloneable
{
public override void Java.Lang.Object Clone () { ... }
}
This results in compilation errors like:
Error CS0115: 'MyClass.Clone()': no suitable method found to override
Beginning in Visual Studio 16.9 (VSMac 8.9), the metadata attribute managedOverride
has been added, allowing one to explicitly tell the bindings process if a method needs to be virtual
or override
.
<attr path="/api/package[@name='com.example']/class[@name='MyClass']/method[@name='clone']" name="managedOverride">virtual</attr>
Now the bindings process knows the method should be virtual
, which fixes the compilation error:
public interface ICloneable
{
Java.Lang.Object Clone ();
}
public class MyClass : Java.Lang.Object, ICloneable
{
public virtual void Java.Lang.Object Clone () { ... }
}
Note: Sometimes you need the opposite: the method is generated as virtual
when it should be override
. Using the value of override
will fix this case:
<attr path="/api/package[@name='com.example']/class[@name='MyClass']/method[@name='clone']" name="managedOverride">override</attr>
Additionally, sometimes the correct code is to omit both virtual
and override
. For example, when the method is in a sealed
type.
In this case, the value none
can be provided:
<attr path="/api/package[@name='com.example']/class[@name='MyClass']/method[@name='clone']" name="managedOverride">none</attr>
The value
none
value was added in .NET 7 / Xamarin.Android 13.1 (Visual Studio 2022 17.4).