Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VB -> C#: Ref extension method not allowed in C# #785

Closed
docfresh opened this issue Nov 4, 2021 · 3 comments
Closed

VB -> C#: Ref extension method not allowed in C# #785

docfresh opened this issue Nov 4, 2021 · 3 comments
Labels
VB -> C# Specific to VB -> C# conversion

Comments

@docfresh
Copy link

docfresh commented Nov 4, 2021

This sample on StackOverflow does not convert

The error is, "CS8337 The first parameter of a 'ref' extension method 'Add' must be a value type or a generic type constrained to struct."

VB.Net input code

Imports System.Runtime.CompilerServices

Public Module MyExtensions
    <Extension()>
    Public Sub Add(Of T)(ByRef arr As T(), item As T)
        Array.Resize(arr, arr.Length + 1)
        arr(arr.Length - 1) = item
    End Sub
End Module

Erroneous output

using System;

namespace FixityVB
{
    public static class MyExtensions
    {        
        public static void Add<T>(this ref T[] arr, T item)
        {
            Array.Resize(ref arr, arr.Length + 1);
            arr[arr.Length - 1] = item;
        }
    }
}

Expected output

//unsure of correct output

Details

CC 8.41

@docfresh docfresh added the VB -> C# Specific to VB -> C# conversion label Nov 4, 2021
@docfresh docfresh changed the title VB -> C#: Extension method does not convert: VB -> C#: Array-resizing extension method does not convert Nov 4, 2021
@docfresh
Copy link
Author

docfresh commented Nov 4, 2021

This may work if you only limit the array to one type

        public static void Add(this string[] arr, string item)
        {
            Array.Resize(ref arr, arr.Length + 1);
            arr[arr.Length - 1] = item;
        }

@GrahamTheCoder
Copy link
Member

I think it just needs where T:struct after the parentheses on the method definition. But we'll need to check the behaviour for classes too

@GrahamTheCoder GrahamTheCoder changed the title VB -> C#: Array-resizing extension method does not convert VB -> C#: Ref extension method requires struct constraint Dec 11, 2021
@GrahamTheCoder GrahamTheCoder changed the title VB -> C#: Ref extension method requires struct constraint VB -> C#: Ref extension method not allowed in C# Dec 12, 2021
@GrahamTheCoder
Copy link
Member

On further reflection, in the example given, even if T is constrained to struct, it's invalid as an extension method in C# because the array isn't a value type, so you'd need to use the ref keyword at the callsite, but can't because the syntax for that doesn't exist.

In your specific case, the most idiomatic option is probably to define a method like this:

        public static T[] Add<T>(this T[] arr, T item)
        {
            var newArr = arr;
            Array.Resize(ref newArr, arr.Length + 1);
            arr[arr.Length - 1] = item;
            return newArr;
        }

Then you would call it like: myArray = myArray.Add(something). You have to be a bit careful of forgetting to assign it afterwards though, so I'd usually call with "WithAppended" or something like that to indicate it returns

In terms of what the converter can do, I think it's best that it just stops it being an extension method and updates any callers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
VB -> C# Specific to VB -> C# conversion
Projects
None yet
Development

No branches or pull requests

2 participants