Home > Mobile >  How to make generic extension method with ref arg in C#
How to make generic extension method with ref arg in C#

Time:11-29

I am trying to remake javascript method "Shift()" to my c# library. The method should return the first item in array and rewrite array to new with correct length. code:

        public static T Shift<T>(this ref T[] array)
        {
            T item = array[0];

            if (array.Length == 1)
            {       
                 array = new T[] { };
                 return item;
            }

            T[] shiftedArray = new T[array.Length - 1];
            for (int i = 1; i < array.Length; i  )
            {
                shiftedArray[i - 1] = array[i];
            }
            array = shiftedArray;

            return item;
        }

I want it to be extension and generic. Any ideas?

CodePudding user response:

shift in js modifies the existing collection, so appropriate approach would be using List<T>. Something like:

public static T Shift<T>(List<T> list)
{
    T item = list[0];
    
    list.RemoveAt(0);

    return item;
}

this ref has a special meaning in C# and can be used with conjunction with structs. For your use case you can see it on special ones - Span and Memory:

public static T Shift<T>(this ref Memory<T> array)
{
    T item = array.Span[0];

    if (array.Length == 1)
    {       
        array = Memory<T>.Empty;
        return item;
    }
    
    array = array.Slice(1);

    return item;
}

public static T Shift<T>(this ref Span<T> array)
{
    T item = array[0];

    if (array.Length == 1)
    {       
        array = Span<T>.Empty;
        return item;
    }
    
    array = array.Slice(1);

    return item;
}

And usage:

Span<int> span = new [] { 1, 2, 3 };
int i1 = span.Shift();
int i2 = span.Shift();

But usually those are used for special high performance scenarios.

CodePudding user response:

I solve it by this but still not extension method:

        public static T Shift<T>(ref IEnumerable<T> collection)
        {
            T firstItem = collection.First();
            collection = collection.Skip(1);
            return firstItem;
        }
  • Related