Изменить ValueType из метода расширения? - PullRequest
13 голосов
/ 26 августа 2009

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

IsVisible = !IsVisible;

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

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

IsVisible.toggle();

Но поскольку логическое значение является типом значения, логическое значение, которое отправляется в метод расширения, является копией исходного логического объекта, а не ссылочным типом.

public static void Toggle(this boolean value)
{
value = !value;
}

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

Я попытался поместить ключевое слово ref перед логическим значением, но это не скомпилировалось. И я до сих пор не нашел причину этого не компилирования, разве это не идеальная функциональность для методов расширения?

public static void Toggle(this ref boolean value)

Я даже пытался привести логическое значение к объекту, который в моей голове превратил бы его в ссылочный тип, и тогда он больше не был бы копией, и изменение было бы передано обратно. Это тоже не сработало.

Таким образом, мой вопрос: возможно ли сделать расширение, передающее изменения назад, или другой способ сделать его еще проще, чем уже есть?

Я знаю, что вполне возможно, что не получится проще или логичнее, чем в верхнем примере, но вы никогда не знаете:)

Заранее спасибо.

Ответы [ 3 ]

11 голосов
/ 26 августа 2009

Примитивные типы неизменны. Вам нужно будет написать свой код вызова следующим образом:

IsVisible = IsVisible.Toggle();

Это лучшее, что вы можете сделать с помощью методов расширения. Обойти это невозможно.

1 голос
/ 01 февраля 2013

В vb.net методы расширения могут быть объявлены для принятия подразумеваемого "this" в качестве параметра ByRef (эквивалентно ref в C #). Такие методы работают примерно так, как и следовало ожидать, но прискорбный факт, что вызов такого метода расширения для чего-либо, кроме изменяемого места хранения (например, для значения свойства, места хранения только для чтения и т. Д.), Заставит компилятор молча передавать ссылку копия параметра, вместо того, чтобы выдавать ошибку компиляции [глупое поведение, учитывая, что в 90% случаев вся точка использования параметра ref будет иметь возможность изменять его при вызове сайт]. К сожалению, хотя C #, как правило, может использовать методы расширения, написанные на vb, он не позволяет передавать параметры ref без ключевого слова ref и не предоставляет никакого легального способа указания ref, кроме случаев использования static- Синтаксис вызова функции.

1 голос
/ 26 августа 2009

в качестве отступления: разве метод расширения не был бы невероятным расходом для чего-то такого простого, как переключение bool?

...