Proposal: Allow readonly ref structs to implement interfaces, but disallow boxing them #1479
Replies: 18 comments
-
That's what shapes will be useful for. I don't think interfaces can work without boxing, as they are an OO concept. |
Beta Was this translation helpful? Give feedback.
-
Via Generic Constraints (though can't current prevent it in the constrained method 😢 ) |
Beta Was this translation helpful? Give feedback.
-
@orthoxerox Are you saying that there is something called 'shapes' in the work that subsumes this idea? Can you link to the relevant proposal? I tried to make a best-effort check for deduplication of proposals, but with over 900 issues right now it's complicated. Even a search for 'shapes' in the open issues yields 3 pages of results. |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
@orthoxerox Neat. Looks like there's a lot going on in this proposal, it may take me some time to sift through and digest. If it does address this concern, I'll go ahead and close this and/or make a relevant comment on that proposal. Like I said, it'll take some time to go over though. |
Beta Was this translation helpful? Give feedback.
-
Would you mind explaining this? |
Beta Was this translation helpful? Give feedback.
-
void Method<T>(T value) where T : IEquatable<T>
{
// What prevents this?
object boxedValue = (object)value;
} |
Beta Was this translation helpful? Give feedback.
-
I'd very much like to use this for inlining purposes, e.g.
Which is currently impossible with ref structs. |
Beta Was this translation helpful? Give feedback.
-
Currently I don't believe ref structs can be used as a generic type arguments, so allowing them to implement interfaces would not actually help anything as far as generic constraints are concerned. For interfaces which are used in a pattern based way, usually you just need to match the pattern, not implement the interface. As such I don't see what benefit this provides. |
Beta Was this translation helpful? Give feedback.
-
@YairHalberstadt true, we'd need to open them up for use in generics too. |
Beta Was this translation helpful? Give feedback.
-
@scalablecory Besides, I don't believe anything in the spec guarantees that generics with struct type arguments will be specialised, and in certain runtimes public struct C<T> where T : struct
{
T Item;
} |
Beta Was this translation helpful? Give feedback.
-
Even if the runtime didn't box them that method could, and the compiler would lose the ability to enforce the necessary lifetimes to keep the |
Beta Was this translation helpful? Give feedback.
-
@HaloFour definitely not implying |
Beta Was this translation helpful? Give feedback.
-
@scalablecory Note this is isn't even about boxing. Here T will be stored on the heap, even if it is not boxed by the runtime: public class C<T>
{
T Item;
} Hence it should be illegal to use a ref struct as a type argument for T. |
Beta Was this translation helpful? Give feedback.
-
My example is not intended to be a solution to @ZacLiveEarth's request. I've provided another use case in favor of allowing interfaces on ref structs. I think if we are to allow interfaces on ref structs, we'd want to enable all the features (where appropriate for
I don't think it's as tough a problem as you're making it out to be. The best solution would require a "ref generic", which would be pretty trivial to implement -- all the checks are there already, we'd just turn them on for those args. |
Beta Was this translation helpful? Give feedback.
-
So you're proposing a new |
Beta Was this translation helpful? Give feedback.
-
@HaloFour yes. |
Beta Was this translation helpful? Give feedback.
-
#2975 goes into this in a lot more detail. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
I'm trying to implement a basic stack-based memory pool that returns Spans to the user of the API. The basic API looks like this...
public static PoolToken Acquire(int length, out Span<T> span);
PoolToken is a struct which would like to implement IDisposable, where Dispose clears the span (if it contains types which have references) and returns the memory to the pool. So, the user can consume the API like so...
using(Acquire(length, out var span)) { /*Do things with span*/ }
Because IDisposable is pattern based, and no boxing is required, this shouldn't violate any of the rules for Span and ref structs.
There may be some other uses for this beyond IDisposable. Other pattern-based code like foreach/IEnumerable may benefit, as may code using pattern matching with generic types like the BoxingAllocations example from Performance Improvements in .Net Core 2.1
Possibly related proposals: #93, #1148
Beta Was this translation helpful? Give feedback.
All reactions