vblang
vblang copied to clipboard
Create ref struct type in VB.net.
While I do my research in .net 5 on meta data of class type, I encounter how ref struct create in C# and I remember @VBAndCs work around on it but suffer the same rule as on C# without compiler check support, my method also suffer from that problem because VB IntelliCode isn't support it so it need to run so runtime could spot an error from ref struct but it can be create in pure VB language; what's need to add on normal structure is IsByRefLike
attribute like this example code.
<System.Runtime.CompilerServices.IsByRefLikeAttribute>
Public Structure ref_struct
Public x, y As int
Public Function [double]() As int
Return x * x
End Function
End Structure
I'm not sure its behavior is the same with C# or not, I rarely use ref struct so could anyone work with ref struct please compare how it work on VB to C# or F# ?
Yes, it is how C# creates ref structs under the hod, and this is reported 2.5 years ago in VB repo and Roslyn repo. VB is fully capable to create and consume ref structs but with no design time safe checks, and this is fine with me as VB already ha a dynamic mode (late binding), where no checks happen before runtime. The problem is that Roslyn is going to cripple vb not to use ref structs, which will deprave VB from using many modern .NET core 5 and 3rd party APIs. See https://github.com/dotnet/roslyn/issues/50118
But, there is still a workaround (if they didn't kill it too):
Anyone wants to consume ref Structs in VB: It just works via option infer on:
Dim x = {1,2, 3}.AsSpan()
So, we can just extend this to allow create new ref structs. We can do this without using the Obsolete
trick, by just defining a simple C# wrapper lib like this:
using System;
using System.Text.Json;
namespace RefStructsExtensions
{
public static class RefLikeExtensions
{
public static Span<T> NewSpan<T>() => new Span<T>();
public static Utf8JsonReader NewUtf8JsonReader() => new Utf8JsonReader();
}
}
It just needs one line per every ref struct overload, and can be auto generated!
Now, I can reference this lib in VB, and just use this:
Dim jsonReader = RefLikeExtensions.NewUtf8JsonReader()
But, the ultimatum solution that I will implement, is forking Roslyn, bypassing any restrictions they add to vb source code to cripple ref structs, compile the source, and distribute the modified VB compiler to replace the original one in the VS installation folder!
@VBAndCs Thanks, does its performance very good ? compare to struct and pure class(no inherit or interface). Recently, I'm try to make a hybrid between class and struct, refence as class but on stack as structure, I found how to create ref struct while test transmutation from class to struct and to array.
they won't add new features, but actually are busy with silently removing existing features https://github.com/dotnet/roslyn/pull/50886
@vbcodec They already said they won't add anything long ago, I don't have any expectation about new feature, I just try to salvage what can I use in VB, the rest I can write it in IL.
This continues to be infuriating. Passing a managed pointer to light this up is bedrock in the CLR so this is a deliberate deprivation. I understand that the logic to guarantee that managed pointers can't escape their scope is not a small thing but guess what - it's not perfect in C# - you can get around it with arrays since arrays are special-cased. The point is, ref structs are fantastic and there are indeed paths in C# that helps you achieve low or zero allocation goals, including not creating defensive copies given proper use of readonly ref structs and [In]. All of that should be available in VB - all of it - every single damn bit of it.
@craigajohnson It's not that good, I test ref struct
and it no difference with normal struct on JIT Asm(CLR), I doubt it's better than normal struct; pointer
is easy to create via CIL or dynamic method, only stack alloc
is real difference and hard to recreate but it still can be done in roundabout way.
I'm more happy they decide to left VB alone, C# being bloat and it might become IE6 of .net, you could see it's lately language feature, C# 7.x is much more impact and frequency use in code then latter version.
The problem is that not making Visual Basic .NET support ref struct
essentially leads to Visual Basic .NET not being usable in .NET 7, because many framework and 3rd party assemblies use it and AsSpan
is no longer usable. I think this feature needs to be added to Visual Basic .NET.
I just converted a working .NET 6 VB project to .NET 7, and AsSpan now causes compile error BC36954 with no help available. Converting the code back to Substring then trolls you with CA1845, telling you to use AsSpan instead of Substring. It's extremely frustrating.
@donr484 Put the code that deals with ref structs in a .net6 dll, then reference it in your .NET 7 app.
That's not a fix. That's an even bigger hassle. What if I want to use other .net 7 features in that code? What if I use .AsSpan or other ref struct dependent features in every single function of my app?
Supporting vb in .net 7, including all the new features is the fix.
If the code worked in .net 6, why was it turned into a compilation error in .net 7? That's even worse than never including a feature to begin with.
The BC36954
error is probably caused by https://github.com/dotnet/roslyn/pull/61113 .
I've reported a bug for this unexpected error. https://github.com/dotnet/roslyn/issues/65392
If the compatibility issue is by design and they won't let VB use ref structs, then my team (maybe also my department or even the whole company) will not trust the .NET team. Our new products will use non-.NET languages. Our existing projects will use forked VB compilers, such as Anthony's ModVB.
@donr484 Put the code that deals with ref structs in a .net6 dll, then reference it in your .NET 7 app.
I agree with @donr484 that this is not a solution. Organizing assemblies sometimes is difficult enough and that just adds another criteria. Especially in cases where you reference NuGet packages that require .NET 7 (and your .NET 6 assemblies would have to reference older versions of those packages). Or in cases where we create .NET 6 assemblies and want to extend their functionality later with code that requires .NET 7 (which would essentially mean we have to split those packages).
Microsoft's statement was pretty clear: "We will do everything necessary to keep it a first class citizen of the .NET ecosystem.". The issues we are experiencing when upgrading to .NET 7 contradicts that statement and that shouldn't be the case.
You seem to miss a big fight here: https://github.com/dotnet/roslyn/issues/50118
They made changes in purpose to make VB.NET unable to use ref structs. So, when I say use a .net 6 dll this is because you have no other choice in VB .NET. So, please join us to help Anthony complete ModVB.
You seem to miss a big fight here: dotnet/roslyn#50118
They made changes in purpose to make VB.NET unable to use ref structs. So, when I say use a .net 6 dll this is because you have no other choice in VB .NET. So, please join us to help Anthony complete ModVB.
I was aware of that discussion. My argument was a little bit different though, because I understand that they're not adding language features as such (like they do with C#), but still maintain VB.Net to be a language usable with .NET. However, with the recent changes, they have essentially made VB.Net useless in .NET 7, because we cannot consume many features of .NET 7 (and third party NuGet packages) because of that limitation.
@CyrusNajmabadi Customers seems unhappy here.
Customers seems unhappy here.
Customers reporting issues are rarely happy.
Just a quick question because I have no idea how that works; apparently the usage of Spans has been allowed in VB.Net (according to https://github.com/dotnet/roslyn/issues/65392); it says "Verified" - any idea when that would be released? Would it come in a .NET 7 SDK update or a Visual Studio Update?