Метод расширения массива Void ничего не делает - PullRequest
1 голос
/ 29 февраля 2020

Я пишу массив и затем использую свой метод расширения, чтобы добавить к нему:

private static void Main(string[] args)
{
    int[] testInts = { 1, 2, 3, 4, 5 };
    testInts.Append(6);

    Console.WriteLine("Test Integers\n");

    foreach (int variable in testInts)
    {
        Console.WriteLine(Convert.ToString(variable));
    }            

    Console.WriteLine("\nPress any key to continue.");
    Console.ReadKey();
}

public static void Append(this int[] arr, int value)
{
    arr = arr.Concat(new[] { value }).ToArray();
}

Но когда он печатает на консоль, он все еще только 1, 2, 3, 4, 5? Но когда я просто использую

testInts = testInts.Concact(new[] { 6 }).ToArray()

Это просто отлично работает? Почему это так и есть ли способ решить эту проблему?

РЕДАКТИРОВАТЬ

Весь смысл того, что я использовал пустоту, заключался в том, что я не хотел использовать

testInt = testInt.Append(6)

Это ДОЛЖНО быть просто testInt.Append(6). Есть ли способ сделать это?

Ответы [ 3 ]

1 голос
/ 29 февраля 2020

Это потому, что массив имеет тип ссылки и NOT тип значения . вам нужно «заменить» массив новым массивом, чтобы получить желаемый результат.

Это работает так, как вы хотите:

 testInts = testInts.Concat(new[] { 6 }).ToArray()

Поскольку вы снова устанавливаете массив при передаче массива (объект ссылочного типа) Вы передаете указатель, который указывает массив (в памяти приложения), поэтому вам нужно заменить его. прочитайте о указателях , если вы хотите лучше понять эту топи c.

Здесь исправлена ​​версия вашего кода, вы увидите, что метод расширения теперь возвращает новый массив целых чисел.

private static void Main(string[] args)
{
    int[] testInts = { 1, 2, 3, 4, 5 };
    testInts =  testInts.Append(6);
    Console.WriteLine("Test Integers\n");
    foreach (int variable in testInts)
    {
        Console.WriteLine(Convert.ToString(variable));
    }
    Console.WriteLine("\nPress any key to continue.");
    Console.ReadKey();
}

public static int[] Append(this int[] arr, int value)
{
    arr = arr.Concat(new[] { value }).ToArray();
    return arr;
}
1 голос
/ 29 февраля 2020

Почему это происходит

Когда вы передаете массив testInts в метод расширения, он на самом деле передает не переменную, а только ссылку. Поэтому, когда вы выполняете присваивание, оно действительно создает локальный массив с шестым значением и присваивает его локальной переменной (не исходной вызывающей).

Вам необходимо передать переменную по ссылке, но это невозможно для методов расширения.

Чтобы лучше это понять, проверьте передаваемые параметры по ссылке , с ключевым словом ref или без него.

Поскольку параметр является Ссылаясь на arr, можно изменить значения элементов массива. Однако попытка переназначить параметр в другое место в памяти работает только внутри метода и не влияет на исходную переменную, обр.

Заставить его работать с методом расширения

using System;
using System.Linq;

public class Program
{
        public static void Main(string[] args)
        {
            int[] testInts = { 1, 2, 3, 4, 5 };
            testInts.Append(ref testInts,6);

            Console.WriteLine("Test Integers\n");

            foreach (int variable in testInts)
            {
                Console.WriteLine(Convert.ToString(variable));
            }            

            Console.WriteLine("\nPress any key to continue.");
        }
}

public static class Extentions {
    public static void Append(this int[] arr, ref int[] arr2, int value)
    {
        arr2 = arr.Concat(new[] { value }).ToArray();
    }
}

Еще один способ заставить его работать

Если вы хотите сделать новое назначение, даже не имеет смысла делать метод расширения.

public static int[] Append(int[] arr, int value)
{
    return arr.Concat(new[] { value }).ToArray();
}

// use like this
arr = Append(arr, 6);
0 голосов
/ 29 февраля 2020

Если вы отлаживаете свое приложение, когда находитесь в методе Append (.., ..), вы увидите, что «arr» имеет значение обновления (1..6) после операции Concat (), но как только управление происходит из метода Append (.., ..), ваш "testInts" будет иметь старое значение (1..5).

Попробуйте обновить код.

public static int[] Append(this int[] arr, int value)
        {
            arr = arr.Concat(new[] { value }).ToArray();
            return arr;
        }

и в main (..)

testInts = testInts.Append(6);

таким образом вы получите ожидаемый результат.

...