C
C#9mo ago
Banana Poop

✅ Using `Func<ReadOnlySpan<char>,bool>` but not allowed due to Pointer Type

I am building a parser, and performance is of concern. So instead of allocating infinite strings whenever I need to take a substring. I'd logically prefer to just take slices of the same buffer using Spans. In addition I want to use Func<ReadOnlySpan<char>,bool> to do some work in helping me parse, which would take in the Span to do some work. However, this is illegal in C# Compiler Error CS0306 due to ReadOnlySpan<char> being a pointer type readonly ref struct. I have considered just making a type, with one function on it, and overriding that in subtypes to get around it, but this is really not suitable. I may for instance wish to compile LINQ expressions at run time, to server as parsers. This has got me stuck since the 'correct' way is illegal, and any other way, is highly comprimised. Thoughts?
8 Replies
canton7
canton79mo ago
Can you just define your own delegate type? public delegate bool MyDelegate(ReadOnlySpan<char> input); or so?
Banana Poop
Banana PoopOP9mo ago
Hmm looks like it works
canton7
canton79mo ago
The problem is with ref struct types being used as generic type parameters. The compiler has rules around what it can and can't do with ref structs, but if all it sees is a generic T, it can't know what special rules apply when T is a ref struct (and Func is, of course, a generic type)
Banana Poop
Banana PoopOP9mo ago
Yes this works completly, I thought for some reason whatever lambda used to define this, would also complain, but it works perfectly. I have never needed to use delegates before (except when interfacing with older style code) so it's interesting to me that they still have uses and aren't fully superceded by Func and Action
canton7
canton79mo ago
Yeah, anything with ref / out needs a custom delegate type as well. And quite often it's just clearer, as you get to name your parameters, rather than having a fairly horrible Func<string, string, bool, bool, bool> etc (Func<T> is, after all, just a convenience delegate T Func<T>() defined in the BCL) https://source.dot.net/#System.Private.CoreLib/src/libraries/System.Private.CoreLib/src/System/Function.cs
Banana Poop
Banana PoopOP9mo ago
Thanks @canton7 this solves everything, and delegate is mucher nicer here (even if it wasn't required, which it is). I may start using my own delegates elsewhere, since it's good for when something isn't just a throw-away type for a random odd job (like value tuples vs record) I guess
canton7
canton79mo ago
Yeah, the downside is that all of linq uses Action/Func, and converting between delegate types is a little bit cumbersome Plus var foo = (int x) => { } is automatically inferred as Action<int> these days. So Action/Func are still a little bit special But, the upsides of being able to name/document your parameters often outweigh that $close
MODiX
MODiX9mo ago
Use the /close command to mark a forum thread as answered
Want results from more Discord servers?
Add your server