#c_sharp #net
Всем привет. Возник вопрос, что означает return this;, который обычно встречается в методах? В пользовательском конструкторе this используется когда, поля класса и аргументы конструктора имеют одинаковое имя, как здесь: public IntValue(int value) { this.value = value; } А что означает return this;, не очень понятно? Я думаю эту запись ввели для сокращения кода, и возможно обойтись как-то без return this;, если такое возможно покажите? Если я правильно понял, то код, который я привёл ниже в реализация интерфейса - IEnumerable возвращает экземпляр класса UserCollection приведенный к базовому интерфейсному типу и this в данном случае это и есть ссылка на экземпляр класса UserCollection? namespace InterIEnumerable { // Класс UserCollection коллекция (набор) объектов класса Element. // Для применения foreach, необходимо, чтобы класс реализовывал интерфейс - IEnumerable. public class UserCollection : IEnumerable, IEnumerator { public Element[] elementsArray = null; public UserCollection() { elementsArray = new Element[4]; elementsArray[0] = new Element("A", 1, 10); elementsArray[1] = new Element("B", 2, 20); elementsArray[2] = new Element("C", 3, 30); elementsArray[3] = new Element("D", 4, 40); } // Указатель текущей позиции элемента в массиве. int position = -1; // ------------------------------------------------------------------------------------------------------------------ // Реализация интерфейса IEnumerator. // Передвинуть внутренний указатель (position) на одну позицию. public bool MoveNext() { if (position < elementsArray.Length - 1) { position++; return true; } else { return false; } } // Установить указатель (position) перед началом набора. public void Reset() { position = -1; } // Получить текущий элемент набора. public object Current { get { return elementsArray[position]; } } // ----------------------------------------------------------------------------------------------------------------- // Реализация интерфейса - IEnumerable. IEnumerator IEnumerable.GetEnumerator() { return this as IEnumerator; } } }
Ответы
Ответ 1
Ээхм. this.value — это не магическая конструкция, означающая «не тот value, а другой, который я имею в виду». this — это ссылка на вполне конкретный объект, и this.value — это совершенно обыкновенное обращение к полю этого объекта. Этот вызов ничем не отличается от вызова obj.value по другой ссылке (если, конечно, тип ссылки obj такой же). Внутри нестатических методов объекта this является ссылкой на этот объект. Вне нестатических методов пользоваться this нельзя. Соответственно, если вы возвращаете ссылку на this, вы возвращаете ссылку на объект, в тором выполняется тот самый метод, откуда вы пытаетесь вернуть значение. Никакой мистики.Ответ 2
Просто чтобы можно было делать не так: var x = new Smth(); x.DoSmth1(); x.DoSmth2(); x.DoSmth3(); x.DoSmth4(); var res = x.Value; а вот так (точнее, чтобы сделать эти записи эквивалентными): var x = new Smth(); var res = x.DoSmth1().DoSmth2().DoSmth3().DoSmth4().Value; потому что это может быть удобнее и позволять исключить лишнюю переменную. Это называется чейнингом (chaining) от слова "chain" - "цепь". кста, а в таких конструкциях есть оверхеад на возвращение обьекта или большее использование стека? Cтек используется так же, как раньше - ничего не меняется, поскольку вызовы последовательные, а не вложенные. Ну, потенциально может быть разница в 8 байт по сравнению с void, но я почти уверен, что возврат будет идти через регистр, а не через стек; да и 8 байт ни на что не влияют, поскольку они не зависят от числа вызовов. Сама по себе операция возврата тоже довольно дешёвая, плюс, она может хорошо сочетаться со следующим вызовом в цепочке (mov переместится из кода вызова в код функции) и получится один лишний возврат на всю цепочку. В общем, я считаю, что никакого оверхэда нет. А если и есть, то ни на что не повлияет - любая операция в коде будет больше, чем этот оверхэд. https://ideone.com/989mWC - все результаты в пределах погрешности html, body, #cs, pre { height: 100%; margin: 0; } pre, #cs { display: block; overflow: auto; font-family: monospace; white-space: pre; } pre { width: 14ch; float: left; border-right: 1px solid; margin-right: 8px; }Успешно #stdin #stdout 0.03s 15972KB 360000 3350 360000 2595 360000 422 360000 287 Успешно #stdin #stdout 0.01s 131648KB 360000 2241 360000 2387 360000 234 360000 308 Успешно #stdin #stdout 0.01s 131776KB 360000 2184 360000 1382 360000 181 360000 238 Успешно #stdin #stdout 0.01s 131712KB 360000 1731 360000 1381 360000 179 360000 237Ответ 3
это ссылка на экхемпляр класса public Object getThis() { return this; } Object me = new Object(); Object result = me.getThis() ;теперь result == meОтвет 4
К другим ответам добавлю что public class MyClass { int value; public SetValue(int value) { this.value /*(1)*/ = value /*(2)*/; } } (1) это value самого объекта. (2) это value из аргумента функции Это удобно, что бы не плодить новых названий аргументов. И реально было задавать например value не через int newValue, что рождает путаницу а с аргументом с аналогичным именем.
Комментариев нет:
Отправить комментарий