Можно ли реализовать свойства на других языках, кроме C #? - PullRequest
2 голосов
/ 23 марта 2009

Во время недавней встречи с C # и WPF мне понравились свойства C #:

public double length_inches
{
    get { return length_metres * 39.0; }
    set { length_metres = value/39.0; }
}

Заметив, конечно, что length_metres может измениться с поля на свойство, и код не должен заботиться. WPF также может с радостью связывать элементы пользовательского интерфейса со свойствами объекта.

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

Забавно, я впервые увидел, что это сделано в VB.Net. Это передний край чистоты ОО.

Вопрос в том, могу ли я воссоздать свойства на других языках, которые я использую чаще, например на javascript, python, php? В javascript, если я установлю переменную на замыкание, не получу ли я снова замыкание, а не результат?

Ответы [ 17 ]

19 голосов
/ 23 марта 2009

Python определенно поддерживает свойства:

class Foo(object):

    def get_length_inches(self):
        return self.length_meters * 39.0

    def set_length_inches(self, val):
        self.length_meters = val/39.0

    length_inches = property(get_length_inches, set_length_inches)

Начиная с Python 2.5, синтаксический сахар существует только для свойств, доступных для чтения, а в 2.6 также доступны для записи:

class Foo(object):

    # 2.5 or later
    @property
    def length_inches(self):
        return self.length_meters * 39.0

    # 2.6 or later
    @length_inches.setter
    def length_inches(self, val):
        self.length_meters = val/39.0
8 голосов
/ 24 марта 2009

В JavaScript :

var object = {
  // .. other property definitions ...
  get length_inches(){ return this.length_metres * 39.0; },
  set length_inches(value){ this.length_metres = value/39.0; }
};
6 голосов
/ 23 марта 2009

В C # свойства в основном просто функция компилятора. Компилятор генерирует специальные методы get_PropertyName и set_PropertyName и обрабатывает вызовы и так далее. Он также устанавливает свойство specialname IL методов.

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

И, конечно, если вы реализуете свой собственный язык .NET, вы можете делать то же, что и компилятор C #.

Из-за деталей реализации, между полями и свойствами существуют небольшие различия. Подробнее см. в этом вопросе .

4 голосов
/ 23 марта 2009

Delphi, из которого происходит C #, обладает свойствами из слова go. И слово идти было около 15 лет назад.

3 голосов
/ 24 марта 2009

Из коробки в VB (это VB 6.0, а не VB.net) и VBScript!

Public Property Get LengthInches() As Double
  LengthInches = LengthMetres * 39
End Property

Public Property Let LengthInches(Value As Double)
  LengthMetres = Value / 39
End Property

Также можно довольно красиво подделать в PHP создание класса, который вы расширяете в сочетании с правилами именования, защищенными членами и магическими функциями. Yuch.

3 голосов
/ 24 марта 2009

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

class Thing
  attr_accessor :length_inches
end

сделает геттер и сеттер для length_inches. За кулисами это просто генерирует это:

class Thing
  def length_inches
    @length_inches
  end
  def length_inches=(value)
    @length_inches = value
  end
end

(аварийный курс Ruby: префикс @ означает, что это переменная экземпляра. return неявно присутствует в Ruby. t.length_inches = 42 автоматически вызовет length_inches=(42), если t является Thingy.)

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

class Thing
  def length_inches
    @length_metres * 39.0
  end
  def length_inches=(value)
    @length_metres = value / 39.0
  end
end
2 голосов
/ 23 марта 2009

Я думаю, что это эквивалент Python

class Length( object ):
    conversion = 39.0
    def __init__( self, value ):
        self.set(value)
    def get( self ):
        return self.length_metres
    def set( self, value ):
        self.length_metres= value
    metres= property( get, set )
    def get_inches( self ):
        return self.length_metres*self.conversion
    def set_inches( self, value ):
        self.length_metres= value/self.conversion
    inches = property( get_inches, set_inches )

Это работает так.

>>> l=Length(2)
>>> l.metres
2
>>> l.inches
78.0
>>> l.inches=47
>>> l.metres
1.2051282051282051
2 голосов
/ 23 марта 2009

Delphi имеет шаблон свойств (с методами Setter и Getter), который также может использоваться в интерфейсах. Свойства с «опубликованной» видимостью также будут отображаться в инспекторе объектов IDE.

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

TFoo = class
private
  FBar: string;
  procedure SetBar(Value: string);
  function GetBar: string;

public
  property Bar: string read GetBar write SetBar;

end;

или (без сеттера / геттера):

TFoo = class
private
  FBar: string;

public
  property Bar: string read FBar write FBar;

end;
2 голосов
/ 24 марта 2009

В Objective-C 2.0 / Какао:

@interface MyClass : NSObject
{
    int myInt;
    NSString *myString;
}

@property int myInt;
@property (nonatomic, copy) NSString *myString;

@end

Тогда в реализации просто укажите:

@synthesize myInt, myString;

Это генерирует средства доступа для этой переменной-члена с соглашениями по присвоению имен, совместимыми с кодированием значения ключа, такими как:

- (void)setMyString:(NSString *)newString
{
    [myString autorelease];
    myString = [newString copy];
}

Экономит много времени, печатая ваши аксессоры.

1 голос
/ 24 марта 2009

К сожалению, я сам еще не пробовал, но я читал, что можно реализовать свойства в PHP с помощью магических методов __set и __get. Вот сообщение в блоге на эту тему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...