You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There are 2 interesting things to "fix" when translating this to C#:
public class ClassB.ChildClass inherits protected class ClassA.ChildClass, which C# doesn't allow
ClassB.ChildClass.createThing () implements the abstract method ClassA.ChildClass.createThing (), but it has a covariant return type
The way we fix (1) is:
Make ClassB.ChildClass inherit from Object instead of ClassA.ChildClass
Copy members from ClassA.ChildClass to ClassB.ChildClass
If we didn't have the covariant return type (2), we would detect that ClassB.ChildClass.createThing () implements ClassA.ChildClass.createThing () and we would generate a virtual method.
However, because of the covariant return type, we cannot make the match and end up generating both a virtual and an abstract createThing ():
This was found while enabling DIM for 4 packages in xamarin/GooglePlayServicesComponents#779. An interesting aspect to investigate is that these instances do not appear to have any relation to interfaces or default methods.
Conceptual issue: the original sample code is inconsistent. The Java code has getThing() methods, while the binding code instead has DoThing() methods. These should be made consistent, and should probably just become createThing()/CreateThing(), as getThing() would become a property when bound, which just complicates discussion.
Discussion:
I think the "problem" is:
Copy members from ClassA.ChildClass to ClassB.ChildClass
While this needs to be done, we can't "just copy" all members from the base into the derived type. We need to copy only non-overridden/"hidden" members.
Method.Matches() doesn't take covariant return types into consideration! It only supports exact matches. Consequently, Method.Matches() doesn't believe that ClassB.ChildClass.createThing() overrides ClassA.ChildClass.createThing(), because the return types don't match. (ClassB != ClassA.)
Finally, note that as per 4ec5d4e, the binding of ClassB.ChildClasscannot inherit from ClassA.ChildClass, as ClassA.ChildClass isn't public. As such:
ClassB.ChildClass should inherit Java.Lang.Object
ClassB.ChildClass.CreateThing() should be virtual, notabstract
Imagine we have the following Java:
There are 2 interesting things to "fix" when translating this to C#:
public
classClassB.ChildClass
inheritsprotected
classClassA.ChildClass
, which C# doesn't allowClassB.ChildClass.createThing ()
implements theabstract
methodClassA.ChildClass.createThing ()
, but it has a covariant return typeThe way we fix (1) is:
ClassB.ChildClass
inherit fromObject
instead ofClassA.ChildClass
ClassA.ChildClass
toClassB.ChildClass
If we didn't have the covariant return type (2), we would detect that
ClassB.ChildClass.createThing ()
implementsClassA.ChildClass.createThing ()
and we would generate avirtual
method.However, because of the covariant return type, we cannot make the match and end up generating both a virtual and an abstract
createThing ()
:This fails with:
as well as several duplicate member errors.
The text was updated successfully, but these errors were encountered: