2010-01-06 5 views
20

Поскольку переменные, объявленные внутри метода, доступны только внутри этого метода, а переменные, объявленные частными в классе, доступны только в классе. Какова цель ключевого слова this? Почему я хочу иметь следующее:Какова цель ключевого слова «this» в C#

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; 
    } 
} 

практиковать свои навыки набора текста?

+6

'this' ключевое слово является экземпляр класса, он будет делать то же самое. Люди, возможно, предпочитают 'this.variablename' над' variablename' для удобочитаемости. –

+5

Небольшое примечание. Я не думаю, что вы хотите что-то возвращать из метода, помеченного как 'void' ... –

+1

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

ответ

36

Есть несколько случаев, когда это имеет значение:

  • Если у вас есть параметр функции и переменную-член с теми же именами, что вам нужно, чтобы иметь возможность различать их:

    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); } 
    } 
    

    Конечно то же самое относится, если вы хотите возвращения ссылку на текущий объект

+0

oops, мои примеры кода не имели большого смысла. Должно быть лучше сейчас. – jalf

+5

Третье место, где вам нужно: привязать к другому конструктору в том же классе. –

+2

Четвертый пример: вызов методов расширения на себя. –

28

В вашем примере это чисто дело вкуса, но здесь тот случай, когда это не так:

private string SomeMethod(string variablename) 
{ 
    this.variablename = variablename; 
    return this.variablename; 
} 

Без this, код будет работать по-другому, назначая параметр себе.

+6

Это все еще вопрос вкуса. Некоторые программисты называют экземпляры полей с префиксом подчеркивания и не должны использовать 'this'. –

+8

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

+5

@ Мартинхо Фернандес - за исключением случаев, когда вы совершаете ошибку и не следуете произвольным рекомендациям, тогда вы действительно смущены. Гораздо лучше использовать функцию языка, чем произвольный механизм именования, чтобы рассказать об отличии ИМО. – tvanfosson

4

Вам нужно this, если ваш параметр метода имеет то же имя, что и поле.

private string variablename; 
private void SomeMethod(string variablename) 
{ 
    this.variablename = variablename+variablename; 
    return this.variablename; 
} 
3
  1. this означает ваш текущий член экземпляра класса не
    а. ваш базовый класс
    b. сфера деятельности
    c. статический член
  2. Чтобы сделать ваш код более читаемым.
3

Первое, что приходит мне в голову, - это читаемость и/или личные предпочтения.

Иногда, когда я работаю с довольно большим классом ... или классом с базовым классом (где я не могу «видеть» некоторые переменные) ... Я использую ключевое слово «this» ... как минимум для intellisense в Visual Studio.

0

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

0

Общее использование с аргументами конструктора, которые имеют такое же имя:

public SomeClass(string variablename) 
{ 
    this.variablename = variablename; 
} 
4

В большинстве случаев, используя this просто загромождает код. Тем не менее, я видел, как он использовался другими программистами, предположительно для запуска intellisense для членов местного класса.

Ключевое слово this также требуется для использования в методах расширения.

public static class MyExtensions 
{ 
    public static int WordCount(this String str) 
    { 
     return str.Split(new char[] { ' ', '.', '?' }, StringSplitOptions.RemoveEmptyEntries).Length; 
    } 
} 
15

Существует много случаев, когда это полезно. Вот один пример:

class Logger { 
    static public void OutputLog (object someObj) { 
     ... 
    } 
} 

class SomeClass { 
    private void SomeMethod() { 
     Logger.OutputLog (this); 
    } 
} 

Вот еще один пример. Предположим, я писал «Стрим».Из метода, который выводит объект, и возвращает ссылку на сам поток, например, так:

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); 
+1

+1 - вам часто нужно использовать «это» в методе, в котором вы хотите передать себя другому объекту. –

+0

@ Эрик: Точно, хорошее резюме. Кроме того, как и во втором примере, который я привел выше, когда вы хотите * вернуть * себя из метода. – Tarydon

4

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

Независимо от того, 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; 
    } 
} 

(Не что этот пример особенно полезен, но вы получите идею)

Edit:. более реалистичным примером является модель событий в .NET:

public class Foo 
{ 
    public EventHandler SomeEvent; 

    public void Bar() 
    { 
     if (SomeEvent != null) 
     { 
      SomeEvent(this, EventArgs.Empty); 
     } 
    } 
} 
+0

. , , спасибо за критику дрянного примера, который я взбивал записной книжкой. , , ;) – andrewWinn

3

За пределами, возможно, Javascript, «это» в основном ключевое слово placeholder, и это наиболее полезно, делая ваше намерение очевидным при написании фрагмента кода.

В основном это поможет с удобочитаемостью.

2

Я почтительно не согласен с некоторыми из другого плакаты. В C# это не просто вопрос вкуса; он также соответствует руководящим принципам Microsoft в стиле C# (как внутри, так и снаружи, хотя они, похоже, не соответствуют их собственным принципам).

Там приведены примеры случаев, когда запись вы использовали не будет работать:

private void DoSomething(object input) 
{ 
    input = input; 
} 

Вместо этого вам нужно будет использовать следующие обозначения:

private void DoSomething(object input) 
{ 
    this.input = input; 
} 
+1

Существует причина, по которой это руководство, а не верховенство закона, которое наказуемо смертью. Существует много рекомендаций, которые могут оказаться непригодными. (См. Обсуждение интерфейсов тегов по сравнению с мета-атрибутами) http: // stackoverflow.com/questions/983037/are-tag-or-marker-interfaces-устаревшие –

+0

Руководства по стилю - дело вкуса. –

+0

Я не согласен с тем, что стилистические рекомендации являются субъективными, но то, что вы говорите, равнозначно: «Заглавные буквы книг - это вопрос вкуса». На самом деле это не вопрос «вкуса». Это вопрос принятых стандартов для стилизации текста. –

3

В первую очередь, это необходимо, когда метод класса должен передать ссылку на объект на какой-либо метод в другом классе.

Например:

class Image 
{ 
    void Refresh() 
    { 
     Screen.DrawImage(this); 
    } 
} 

В отличие от некоторых других сценариев, в которых используют или не используя "это." является вопросом стиля, или средством разрешения искусственной двусмысленности.

2

this относится к экземпляру класса, и в примере, который вы нам показываете: вы используете this для ссылки на поле variablename.

Если у вас есть локальная переменная или параметр с тем же именем, вам нужно будет различать между ними. В этом случае this будет ссылаться на это поле, в то время как не префикс this относится к локальной переменной или параметру.

У вас должно быть соглашение об именах, которое поможет вам различать поля и местные жители. Это избавит вас от проблем, которые могут возникнуть, если позднее вы добавите локальное имя с таким же именем в свой метод. (Так как код без this затем перерыв ...)

0

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) Во-вторых, в и метод расширения:

public class Extension 
{ 
public Element Root(this Element element) { 
    if(element.Parent == null) 
    return element; 
    return element.Parent.Root(); 
} 
} 

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

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; 
} 
} 
5

В дополнении к «полям неоднозначности» и «передача ссылки текущего 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. я нахожу это немного ... «несбалансированным».

+0

У меня «было», чтобы использовать это, когда базовый класс имел методы расширения, чтобы обеспечить более простой интерфейс для некоторых операций. –

+0

И на самом деле это особый случай «передать ссылку на себя», за исключением того, что он (синтаксис) покрыт сахаром. –

0

Существует один принцип, который должен помочь вам решить, использовать или не использовать это. Вам нужно конкретно обратиться к ЭТОУ экземпляру класса? Если да, используйте «это». В противном случае оставьте это.

Примером этого может служить другой пример плагина. Он не мог полагаться на неявное это, поскольку ему нужен был сам объект.

Нет смысла использовать 'this' в качестве префикса для метода самого класса в самом классе, поскольку он неявный.

0

Я не могу помочь, но ...

if (this == null) 
    throw new NullReferenceException(); 

[KIDDDIIIING !!!]

0

Другой сценарий I'v уже найдено:

private int value; 
public int Value 
{ 
    get { return this.value; } 
    set { this.value = value; } //without this it doesn't make sense 
} 
+1

это не сработает, потому что вы назвали поле поддержки '_value', а не' value'. – Oliver

+0

@ Oliver, yap +1 для вас, исправлено мной. – Dariusz

Смежные вопросы