Android interfaces are written in Java, and can therefore now have default implementations on members. Xamarin won't be able to seamlessly project those interfaces into .NET.
On iOS, Objective-C and Swift have protocols, of the general shape:
[The current proposal](https://github.com/dotnet/csharplang/blob/master/proposals/default-interface-methods.md) is to allow the following in interfaces:
This gives parity with where Java is: they made tweaks over time based on feedback, and this is where they landed (private and static members were added).
That means you can't "just" refactor similar implementations into an interface the way you do into a base class.
# Overriding and base calls
Should overrides be able to call `base`? Yes, but we would need new syntax to deal with ambiguity arising from the fact that you can have more than one base interface:
`I4` above inherits two default implementations, one each from `I2` and `I3`, but explicitly provides a new implementation, so that there's never a doubt as to which one applies. However, imagine:
The class declaration of `C` above must certainly be an error, since there is no good (symmetric) unambiguous way of determining a default implementation. Also, the interface declaration of `I5` should be an error, or at least a warning.
This means that adding an override to an interface can break existing code. This can happen in source, but depending on compilation order, it may also be possible to successfully compile such code.
The feature reveals some "seams" between C# and the CLR in how they understand interface overriding. In the following, imagine `I`, `C` and the consuming code are in three different assemblies:
The problem here is that the runtime doesn't consider non-virtual members able to implement interface members, but C# does. To bridge the gap, C# generates a hidden virtual stub method to implement the interface member. However, during step 1 there is no interface member to implement, and during step 2 the class declaration isn't recompiled. The runtime doesn't consider `C.M` an implementation of `I.M`, so if you call `M` on a `C` through the `I` interface, you get the default behavior. As soon as `C` is recompiled, however, the compiler inserts its stub, and the behavior changes.