vblang icon indicating copy to clipboard operation
vblang copied to clipboard

Create ref struct type in VB.net.

Open RevensofT opened this issue 4 years ago • 18 comments

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# ?

RevensofT avatar Feb 02 '21 12:02 RevensofT

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

VBAndCs avatar Feb 02 '21 12:02 VBAndCs

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 avatar Feb 02 '21 12:02 VBAndCs

@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.

image

RevensofT avatar Feb 02 '21 12:02 RevensofT

they won't add new features, but actually are busy with silently removing existing features https://github.com/dotnet/roslyn/pull/50886

vbcodec avatar Feb 02 '21 14:02 vbcodec

@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.

RevensofT avatar Feb 02 '21 16:02 RevensofT

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 avatar Feb 10 '21 07:02 craigajohnson

@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.

RevensofT avatar Feb 11 '21 08:02 RevensofT

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.

BerndPodhradsky avatar Nov 09 '22 02:11 BerndPodhradsky

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 avatar Nov 12 '22 01:11 donr484

@donr484 Put the code that deals with ref structs in a .net6 dll, then reference it in your .NET 7 app.

VBAndCs avatar Nov 12 '22 13:11 VBAndCs

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.

donr484 avatar Nov 12 '22 14:11 donr484

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.

Nukepayload2 avatar Nov 12 '22 15:11 Nukepayload2

@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.

BerndPodhradsky avatar Nov 12 '22 16:11 BerndPodhradsky

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.

VBAndCs avatar Nov 12 '22 23:11 VBAndCs

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.

BerndPodhradsky avatar Nov 12 '22 23:11 BerndPodhradsky

@CyrusNajmabadi Customers seems unhappy here.

VBAndCs avatar Nov 13 '22 00:11 VBAndCs

Customers seems unhappy here.

Customers reporting issues are rarely happy.

CyrusNajmabadi avatar Nov 13 '22 03:11 CyrusNajmabadi

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?

BerndPodhradsky avatar Nov 30 '22 17:11 BerndPodhradsky