-
Notifications
You must be signed in to change notification settings - Fork 57
C#9 Covariant Return Types #649
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Note that in .NET 5, the runtime has more restrictions that the C# spec. Covariant return types are for classes only:
Not sure how this compares to the Java covariant return types, but it's something to watch out for, potentially. (Particularly the first restriction) |
Additional restrictions I found that are allowed in Java but not in C#9:
|
This can be supported via explicit interface implementation: interface ICloneable {
object Clone();
}
class MyClass : ICloneable {
object ICloneable.Clone() {return Clone(); }
public virtual MyClass Clone() {return this;}
} |
This worked for me? class A {
public virtual object[] M() {return null;}
}
class B : A {
public override string[] M() {return null;}
} |
Answer: No (?)! At least with current .NET 5.0.103, given: // Assembly: Base.dll
public class Base {
public virtual Base M() {return this;}
}
// Assembly: Derived.dll - v1.0
public class Derived : Base {
public override Base M() {return this;}
}
// Assembly: App.dll
public class App {
static void Main(string[] args)
{
Derived d = new Derived ();
d.M();
}
} This is normal C#8 code; no covariant return types. As expected,
If we change // Assembly: Derived.dll - v2.0
public class Derived : Base {
public override Derived M() {return this;}
} Re-running From this we can infer that changing a method override to use covariant return types is an ABI-compatible change. (At least for this simple scenario.) I think this might even be a source-compatible change as well, though it will cause var d = new Derived();
var m = d.M();
class MaybeRelevant {
public static void M(Base b) {}
public static void M(Derived d) {}
}
…
MaybeRelevant.M(new Derived().M()); A different |
@jpobst: with this in mind, how crazy/impossible would it be to prototype covariant return type support in |
I am not sure what you mean by covariant return type support in Then when Thus in a .NET6 world, For example, if we wanted to convert |
Closing issue as this does not appear to require any support from JI. |
C#9 will reportedly support covariant return types, which in many ways mirrors Java covariant return types.
Covariant return types is a feature in which a subclass of a type can be specified in a method override in a derived type; consider Java:
Because
StringBuilder
ISAAppendable
,StringBuilder
can be used as theAppendable.append(char)
return type instead of usingAppendable
.Compare to the existing Xamarin.Android
Java.Lang.StringBuilder.Append(char)
binding, in whichIAppendable
must be returned, because C# lacks covariant return types.This is a welcome development, and means that it would (presumably) be easier to deal with binding them; see also #216.
Unknown concern #1: what does this do with assembly versioning? If e.g.
Mono.Android.dll
v12 embraces covariant return types such thatStringBuilder.Append()
now returnsStringBuilder
instead ofIAppendable
, will that break existing code?For most circumstances, @jonpryor can't see any issues with emitting covariant return types, mirroring what Java does. (Assuming that we can, based on the previously mentioned ABI compatibility question.)
Collection Interfaces
Once area where there will be problems is around collection interfaces. Consider Issue #647, in which
generator
currently wants to bindDownloadDrawablesAsync.doInBackground()
, a method which returns ajava.util.HashMap<String, Drawable>
, as aSystem.Collections.Generic.IDictionary<string, Drawable>
. This is "friendlier" to consume, as a C# consumed, but there is no way forIDictionary<TKey, TValue>
to be a subclass ofJava.Util.HashMap
.It is plausible that, since we already special-case collection interfaces, they will need to continue to be special-cased.
The text was updated successfully, but these errors were encountered: