-
Notifications
You must be signed in to change notification settings - Fork 63
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
nonevalue was added in .NET 7 / Xamarin.Android 13.1 (Visual Studio 2022 17.4).