Общая сложность свопа

Я иду из С++, где легко сделать что-то вроде этого:

template<class T>
void Swap(T &a, T &b)
{
  T temp = a;
  a = b;
  b = temp;
}

а затем использовать его для замены значений в контейнере:

std::vector<int> someInts;
someInts.push_back(1);
someInts.push_back(2);

Swap(someInts[0], someInts[1]);

Однако при попытке сделать то же самое в С#

void Swap<T>(ref T a, ref T b)
{
        T temp = a;
    a = b;
    b = temp;
}

Я получаю ошибку "свойство или индексатор не может быть передан как параметр out или ref"

Почему это и как я могу его преодолеть?

Большое спасибо

Ответ 1

Вы не можете использовать параметры индексатора или свойства ref. Причина в том, что вы перенастраиваете ссылку на объект, но не на местоположение, поэтому любое действие, которое функция могла бы не изменить, не изменит источник, поскольку он не будет записывать его обратно в местоположение (т.е. Не вызывать сеттер в случае имущество). Вам нужно передать массив в метод, чтобы метод мог устанавливать значения как индексы, так и знать, какие значения следует менять.

Ответ 2

Свойства и индексатор - фактически методы (созданные компилятором за кулисами), поэтому я полагаю, что для них невозможно выполнить вызов по ссылке. Однако вы можете написать такой метод:

public void Swap<T>(T[] data, int a, int b) {
  T temp = data[a];
  data[a] = data[b];
  data[b] = temp;
}

Swap(someInts, 0, 1);