Proposal: Covariance and Contravariance between T and Nullable(T) #1301
Replies: 11 comments
-
"may be a thing"? |
Beta Was this translation helpful? Give feedback.
-
Definitely not a thing. The runtime doesn't support value type covariance and even if you somehow manage to convince the runtime team to try to do make it work (and that won't happen) there's still significant technical hurdles to get it to work. Covariance works with reference types because converting between reference types is a no-op (except, of course, the type check that's required to maintain type safety in some cases). Converting between value types is not a no-op (except in some rather special circumstances), some piece of code somewhere needs to take an |
Beta Was this translation helpful? Give feedback.
-
I see. So it seems implicit conversions like this eventually need help from API level. Maybe it can be done with "syntax sugar" in compile time but many details need to be figured out. Thanks for your reply. |
Beta Was this translation helpful? Give feedback.
-
The only thing that the C# compiler could do is creating a new object that "wraps" the existing object. Basically it could do the equivalent of code that you can write yourself: Action<int> after = index => before(index);
Func<int, int?> after = index => before(index);
IEnumerable<int?> after = before.Select(i => (int?)i); That's not a good idea because it turns something that looks like reference conversion into something that looks more like boxing/value conversion - reference identity is lost, objects are allocated, there are extra indirections etc. |
Beta Was this translation helpful? Give feedback.
-
What if |
Beta Was this translation helpful? Give feedback.
-
Implicit or not, any sort of conversion between value types is still "some piece of code somewhere". |
Beta Was this translation helpful? Give feedback.
-
With Non-nullable Reference Types, something like this will be badly needed. |
Beta Was this translation helpful? Give feedback.
-
Why?! |
Beta Was this translation helpful? Give feedback.
-
@mikedn say you have an interface like interface IMayHaveValue<out T>
{
T? Value { get; }
} and another interface interface IHasValue<out T>: IMayHaveValue<T>
{
new T Value { get; }
} A variant relationship between would them enable you to write a method like static IEnumerable<IHasValue<T>> HavingValues<T>(this IEnumerable<IMayHaveValue<T>> xs) =>... In other words, with Granted, this is my perspective after spending time with TypeScript a language where nullability is fundamental. But that language is structurally typed. Currently I find the proposed C# feature neither ergonomic nor expressive. EDIT: fixed example to make sense. |
Beta Was this translation helpful? Give feedback.
-
Hmm, I'm not familiar enough with non-nullable references to tell if not having nullable value type covariance has any meaning in that context. However, non-nullable references (and note how I keep omitting the word "type") are quite different from nullable value types. There are no actual nullable/non-nullable reference types, So, it's very unlikely that this issue has anything to do with non-nullable references. |
Beta Was this translation helpful? Give feedback.
-
@mikedn I see what you mean. Basically I was using the context as an excuse to complain |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
As title says, let us see following three examples:
Currently all three examples will cause compilation errors which basically share same issue. However, from a logical aspect, all implicit conversions in three examples seem feasible and do not violate current type system in C#. The Covariance and Contravariance between
T
andNullable<T>
in generic interfaces and delegates may be a thing.Beta Was this translation helpful? Give feedback.
All reactions