Какова цель ключевого слова 'this' в С#
Так как переменные, объявленные внутри метода, доступны только внутри этого метода, а переменные, объявленные частными в классе, доступны только в классе. Какова цель ключевого слова this
? Почему я хочу иметь следующее:
private static class SomeClass : ISomeClass
{
private string variablename;
private void SomeMethod(string toConcat)
{
this.variablename = toConcat+toConcat;
return this.variablename;
}
}
Когда это будет делать то же самое:
private static class SomeClass : ISomeClass
{
private string variablename;
private void SomeMethod(string toConcat)
{
variablename = toConcat+toConcat;
return variablename;
}
}
чтобы практиковать свои навыки набора текста?
Ответы
Ответ 1
Есть несколько случаев, когда это имеет значение:
-
Если у вас есть параметр функции и переменная-член с одинаковыми именами, вы должны иметь возможность различать их:
class Foo {
public Foo(int i) { this.i = i; }
private int i;
}
-
Если вам действительно нужно ссылаться на текущий объект, а не на один из его членов. Возможно, вам нужно передать его другой функции:
class Foo {
public static DoSomething(Bar b) {...}
}
class Bar {
public Bar() { Foo.DoSomething(this); }
}
Конечно же, если вы хотите вернуть ссылку на текущий объект
Ответ 2
В вашем примере это чисто дело вкуса, но вот случай, когда это не так:
private string SomeMethod(string variablename)
{
this.variablename = variablename;
return this.variablename;
}
Без this
, код будет работать по-другому, присваивая параметр самому себе.
Ответ 3
Есть много случаев, когда это полезно. Вот один пример:
class Logger {
static public void OutputLog (object someObj) {
...
}
}
class SomeClass {
private void SomeMethod () {
Logger.OutputLog (this);
}
}
Вот еще один пример. Предположим, что я писал метод Stream.Out, который выводит объект и возвращает ссылку на сам поток, например:
class Stream {
public Stream Out (object obj) {
... code to output obj ...
return this;
}
}
Затем можно использовать этот вызов Out в цепном режиме:
Stream S = new Stream (...);
S.Out (A). Out (B). Out (C);
Ответ 4
В дополнение к ответам "полевые неоднозначности" и "передаче ссылки текущего isntance" (уже задано) существует дополнительный сценарий, где this
необходим; для вызова методов расширения в текущем экземпляре (я игнорирую использование this
в объявлении метода расширения, поскольку это не совсем то же самое значение, что и вопрос):
class Foo
{
public void Bar()
{
this.ExtnMethod(); // fine
ExtnMethod(); // compile error
}
}
static class FooExt
{
public static void ExtnMethod(this Foo foo) {}
}
Чтобы быть справедливым, это не общий сценарий. Скорее всего, это просто сделать код более читаемым, например:
public bool Equals(Foo other) {
return other != null && this.X == other.X && this.Y == other.Y;
}
В приведенном выше (или аналогично для Compare
, Clone
и т.д.) без this.
я нахожу его немного... "неуравновешенным".
Ответ 5
Вам нужен this
, если ваш параметр метода имеет то же имя, что и поле.
private string variablename;
private void SomeMethod(string variablename)
{
this.variablename = variablename+variablename;
return this.variablename;
}
Ответ 6
В большинстве случаев использование this
просто загромождает код. Тем не менее, я видел, как он использовался другими программистами, предположительно для запуска intellisense для членов локального класса.
Ключевое слово this
также требуется для использования в методах расширения.
public static class MyExtensions
{
public static int WordCount(this String str)
{
return str.Split(new char[] { ' ', '.', '?' }, StringSplitOptions.RemoveEmptyEntries).Length;
}
}
Ответ 7
Во-первых, ваши примеры ошибочны, потому что вы пометили класс как статический, поэтому его нельзя создать.
Независимо, this
- это просто ссылка на текущий экземпляр. Он может использоваться для разрешения конфликтов между локальными переменными и переменными-членами, например:
public class Foo
{
private string baz;
public void Bar(string baz)
{
this.baz = baz;
}
}
Его также можно использовать просто как самостоятельный объект, например:
public class Foo
{
public List<Foo> GetList(string baz)
{
var list = new List<Foo>();
list.Add(this);
return list;
}
}
(Не то, чтобы этот пример особенно полезен, но вы получаете идею.)
Изменить: Более реалистичным примером является модель событий в .NET:
public class Foo
{
public EventHandler SomeEvent;
public void Bar()
{
if (SomeEvent != null)
{
SomeEvent(this, EventArgs.Empty);
}
}
}
Ответ 8
-
this
означает ваш текущий экземпляр класса экземпляра, а не
а. ваш базовый член класса
б. член области
с. статический член
- Чтобы сделать ваш код более читаемым.
Ответ 9
Первое, что приходит мне в голову, - это читаемость и/или личные предпочтения.
Иногда, когда я работаю с довольно большим классом... или классом с базовым классом (где я не могу "видеть" некоторые переменные)... Я использую ключевое слово "this"... как минимум для intellisense в Visual Studio.
Ответ 10
За пределами, возможно, Javascript, "this" в основном является ключевым словарем-заполнителем, и наиболее полезно сделать ваше намерение очевидным при написании фрагмента кода.
В основном это поможет с удобочитаемостью.
Ответ 11
Прежде всего, это необходимо, когда метод класса должен передать ссылку на объект на какой-либо метод в другом классе.
Например:
class Image
{
void Refresh()
{
Screen.DrawImage(this);
}
}
В отличие от некоторых других сценариев, где использование или отсутствие использования этого ". является вопросом стиля или средством разрешения искусственной двусмысленности.
Ответ 12
Я почтительно не согласен с некоторыми другими плакатами. В С# это не просто вопрос вкуса; он также соответствует руководящим принципам Microsoft С# (как внутри, так и снаружи, хотя они, похоже, не соответствуют их собственным принципам внутри).
Есть примеры случаев, когда используемая вами нотация не будет работать:
private void DoSomething(object input)
{
input = input;
}
Вместо этого вам нужно будет использовать следующие обозначения:
private void DoSomething(object input)
{
this.input = input;
}
Ответ 13
this
относится к экземпляру класса, и в примере, который вы нам показываете: вы используете this
для ссылки на поле под названием variablename
.
Если у вас есть локальная переменная или параметр с тем же именем, вам нужно будет различать между ними. В этом случае this
будет ссылаться на поле, а не на префикс с this
ссылается на локальную переменную или параметр.
У вас должно быть соглашение об именах, которое поможет вам различать поля и локальные жители. Это избавит вас от проблем, которые могут возникнуть, если позднее вы добавите локальное имя с таким же именем в свой метод. (Так как код без this
будет прерывать...)
Ответ 14
В первую очередь это проблема стиля. Если ваш метод имеет имя переменной, то же самое, что и частный член класса, использование этого помогает устранить неоднозначность. Это может потенциально предотвратить глупые ошибки.
Ответ 15
Обычно используется аргумент конструктора с тем же именем:
public SomeClass(string variablename)
{
this.variablename = variablename;
}
Ответ 16
1) Во-первых, и самое главное, это ситуация, когда объект должен передать ссылку себе:
public class Element{
//...
public Element Parent;
public Element Root()
{
if( Parent == null )
return this;
return Parent.Root();
}
}
public void OnEvent()
{
Event(this, new EventArgs());
}
В свободном интерфейсе:
public class Query {
public Query Add (параметр параметра) {_list.Add(параметр); верните это; }
}
2) Во-вторых, метод in и extension:
public class Extension
{
public Element Root(this Element element) {
if( element.Parent == null )
return element;
return element.Parent.Root();
}
}
3) В-третьих, вам это действительно не нужно, чтобы отличать параметры от членов класса.
Это вам не нужно, потому что хорошее соглашение о кодировании избавляет вас от использования ключевого слова 'this'.
public class Element
{
public Element Parent;
publlc void SetParent(Element parent)
{
// this.Parent = parent; // see, you don't need it
Parent = parent;
}
}
//...
public class Element
{
public Element _parent;
public Element Parent { get { return _parent; } }
publlc void SetParent(Element parent)
{
// this._parent = parent; // see, you don't need it
_parent = parent;
}
}
Ответ 17
Существует один принцип, который должен помочь вам решить, использовать или не использовать 'this'. Вам нужно конкретно обратиться к ЭТОУ экземпляру класса? Если вы это сделаете, используйте 'this'. В противном случае оставьте это.
Примером этого может служить пример Logger другого плаката. Он не мог полагаться на неявное это, поскольку ему нужен был сам объект.
Нет смысла использовать 'this' в качестве префикса для метода самого класса, в самом классе, поскольку он неявный.
Ответ 18
Я не могу не...
if (this == null)
throw new NullReferenceException();
[KIDDDIIIING!!!]
Ответ 19
Другой сценарий, который я уже нашел:
private int value;
public int Value
{
get { return this.value; }
set { this.value = value; } //without this it doesn't make sense
}