views:

676

answers:

17

During a bout of C# and WPF recently, I got to like C#'s properties:

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

Noticing, of course, that length_metres may change from being a field to a property, and the code need not care. WPF can also bind UI elements to object properties very happily.

When I first learnt about classes and objects, I assumed that there was a way to do it, because it seemed so obvious! The point of hiding complexity inside a class is that you don't need to care what is being stored any more. But it has taken until now to see it.

Amusingly, I first saw it done in VB.Net. That leading edge of OO purity.

The question is, can I recreate properties in other languages which I use more often, like javascript, python, php? In javascript, if I set a variable to a closure, won't I get the closure back again, rather than the result of it?

+1  A: 

It's definitely possible to implement properties in other languages. VB and F# for example have explicit property support. But these both target the CLR which has property support.

VB.

Public Property Name As String 
  Get 
    return "someName"
  End Get
  Set
    ...
  End Set
End Property

I do not believe javascript or PHP supports property syntax but I'm not very familiar with those languages. It is possible to create field get/set accessor methods in pretty much any language which simulate properties.

Under the hood, .Net properties really just result down to get/set methods. They just have a really nice wrapper :)

JaredPar
+6  A: 

In C# properties are mostly just a compiler feature. The compiler generates special methods get_PropertyName and set_PropertyName and works out the calls and so forth. It also set the specialname IL property of the methods.

If your language of choice supports some kind of preprocessor, you can implement something similar but otherwise you're pretty much stuck with what you got.

And of course, if you're implementing your own .NET language you can do what the C# compiler does as well.

Due to the implementation details, there are actually subtle differences between fields and properties. See this question for details.

Brian Rasmussen
+1: I was going to call it compiler magic, but I guess "compiler feature" works, too. ;)
R. Bemrose
It's slightly more than a compiler feature because properties are recognizable at an IL level. They just are special cased by the Compiler to be nicer :)
JaredPar
-1: Properties are a feature of the .NET framework not only of C#!
rstevens
+1: Cmon man. Quit nitpicking... also notice the 2nd to last paragraph.
zildjohn01
-1, it's not nitpicking. It's just wrong.
Samuel
Nitpicking or not - it certainly wasn't completely correct as written. I have clarified the text.
Brian Rasmussen
+1 for an open mind and not coming after people who down-voted.
jeffjose
A: 

The convention is to implement a get_PropertyName() and a set_PropertyName() method (that's all it is in the CLR as well. Properties are just syntactic sugar in VB.NET/C# - which is why a change from field to property or vice-versa is breaking and requires client code to recompile.

public int get_SomeValue() { return someValue; }
public void set_SomeValue(int value) { someValue = value; }
private int someValue = 10;

// client
int someValue = someClass.get_SomeValue();
someClass.set_SomeValue(12);
Mark Brackett
Properties are known in .NET framework (you can "play" with them via Reflection). They are not only syntactic sugar!
rstevens
@rstevens - Yes, there is a .property directive in IL - but I think it's just metadata. A call to get or set the property is just a method call to the get_* or set_* methods.
Mark Brackett
+1  A: 

Delphi has a property pattern (with Setter and Getter methods), which also can be used in interfaces. Properties with "published" visibility also will be displayed in the IDE object inspector.

A class definition with a property would look like this:

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

public
  property Bar: string read GetBar write SetBar;

end;

or (without Setter / Getter):

TFoo = class
private
  FBar: string;

public
  property Bar: string read FBar write FBar;

end;
mjustin
+18  A: 

Python definitely supports properties:

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)

Starting in Python 2.5, syntactic sugar exists for read-only properties, and in 2.6, writable ones as well:

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
Jarret Hardie
+1 as i was about to post the same ;-)
ChristopheD
True, but it isn't nearly as neat and tidy as C#.
Greg
Not as neat and tidy, bug you can add some more sugar yourself. Also it's a tiny bit more flexible because you have access to the underlaying descriptor protocol that implements it which allows some neat tricks.
Armin Ronacher
Thanks for the edit, Ben. Haven't looked into 2.6 much, so glad to see this improvement!
Jarret Hardie
+1 got property.setter
MizardX
You can even delete the attribute if you define a delete function. Try that in any static language ;)
Ber
To the neat and tidy comment. My first reaction was - python is very neat. But after looking at your snippet, I see your point. But believe me, python otherwise is the most neat language I've seen.
jeffjose
+2  A: 

I think this is the Python equivalent

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 )

It works like this.

>>> l=Length(2)
>>> l.metres
2
>>> l.inches
78.0
>>> l.inches=47
>>> l.metres
1.2051282051282051
S.Lott
A: 

ActionScript 3 (javascript on steroids) has get/set syntax also

Scott Evernden
+3  A: 

Delphi, from which C# is derived, has had properties from the word go. And the word go was about 15 years ago.

anon
C# is derived from Delphi??? Good to know! Is C++ derived from Assembler language?
rstevens
C# is derived from Delphi in the sense that the designer of C# is Anders, who also designed Delphi before Microsoft poached him from Borland. Lexigraphically C# derives from C++, but there's more than the odd ghost of Delphi in the way C# does things
Cruachan
Delphi was the language that anders designed before C#. C#, not suprisingly, takes a lot of the lessons learned from Delphi and improves on them.
anon
+1  A: 

Sadly, I haven't tried it myself yet, but I read that it was possible to implement properties in PHP through __set and __get magic methods. Here's a blog post on this subject.

MiseryIndex
A: 

You can make something like it with PHP5 magic functions.

class Length {
    public $metres;
    public function __get($name) {
     if ($name == 'inches')
      return $this->metres * 39;
    }
    public function __set($name, $value) {
        if ($name == 'inches')
      $this->metres = $value/39.0;
    }
}

$l = new Length;
$l->metres = 3;
echo $l->inches;
OIS
+3  A: 

Most dynamic languages support something like that. In Smalltalk and Ruby, fields are not directly exposed - The only way to get at them is through a method. In other words - All variables are private. Ruby has some macros (class methods really), to make it simpler to type:

class Thing
  attr_accessor :length_inches
end

will make a getter and a setter for length_inches. Behind the scenes, it's simply generating this:

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

(Ruby crash-course: The @ prefix means it's an instance variable. return is implicit in Ruby. t.length_inches = 42 will automatically invoke length_inches=(42), if t is a Thingy.)

If you later on want to put some logic in the getters/setters, you can simply manually implement the same methods:

class Thing
  def length_inches
    @length_metres * 39.0
  end
  def length_inches=(value)
    @length_metres = value / 39.0
  end
end
troelskn
+7  A: 

In 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; }
};
Zach
actually i was searching for this one, thx alot
Cem Kalyoncu
I was excited about this feature until I tested it in IE, which doesn't support it. Sample script: http://pastebin.com/BRUsUEpA
kaneuniversal
A: 

You could do it in all sorts of languages, with varying degrees of syntactic sugar and magic. Python, as already mentioned, provides support for this (and, using decorators you could definitely clean it up even more). PHP could provide a reasonable facsimile with appropriate __get() and __set() methods (probably some indirection to . If you're working with Perl, you could use some source filters to replicate the behavior. Ruby already requires everything to go through

Sean McSomething
A: 

When I first played with Visual Basic (like, version 1 or something) the first thing I did was try to recreate properties in C++. Probably before templates were available to me at the time, but now it would be something like:

template <class TValue, class TOwner, class TKey>
class property
{
    TOwner *owner_;

public:
    property(TOwner *owner)
        : owner_(owner) {}

    TValue value() const
    {
        return owner_->get_property(TKey());
    }

    operator TValue() const
    {
        return value();
    }

    TValue operator=(const TValue &value)
    {
        owner_->set_property(TKey(), value);
        return value;
    }
};

class my_class
{
public:
    my_class()
        : first_name(this), limbs(this) {}

    struct limbs_k {};
    struct first_name_k {};

    property<std::string, my_class, first_name_k> first_name;
    property<int, my_class, limbs_k> limbs;

    std::string get_property(const first_name_k &);
    void set_property(const first_name_k &, const std::string &value);

    int get_property(const limbs_k &);
    void set_property(const limbs_k &, int value);
};

Note that the "key" parameter is ignored in the implementations of get_property/set_property - it's only there to effectively act as part of the name of the function, via overload resolution.

Now the user of my_class would be able to refer to the public members first_name and limbs in many situations as if they were raw fields, but they merely provide an alternative syntax for calling the corresponding get_property/set_property member functions.

It's not perfect, because there are some situations where you'd have to call value() on a property to get the value, whenever the compiler is unable to infer the required type conversion. Also you might get a warning from the passing of this to members in the constructor, but you could silence that in this case.

Daniel Earwicker
+2  A: 

Out of the box in VB (that's VB 6.0, not VB.net) and VBScript!

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

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

Also possible to fake quite nicely in PHP creating a class that you extend in combination with naming guidelines, protected members and magic functions. Yuch.

svinto
+1  A: 

In Objective-C 2.0 / Cocoa:

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

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

@end

Then in the implementation, simply specify:

@synthesize myInt, myString;

This generates the accessors for that member variable with key-value-coding compliant naming conventions like:

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

Saves a lot of work typing out your accessors.

Jasarien
A: 

Boo is a .NET language very similar to Python, but with static typing. It can implement properties:

class MyClass:
    //a field, initialized to the value 1
    regularfield as int = 1 //default access level: protected

    //a string field
    mystringfield as string = "hello"

    //a private field
    private _privatefield as int

    //a public field
    public publicfield as int = 3

    //a static field: the value is stored in one place and shared by all
    //instances of this class
    static public staticfield as int = 4

    //a property (default access level: public)
    RegularProperty as int:
        get: //getter: called when you retrieve property
            return regularfield
        set: //setter: notice the special "value" variable
            regularfield = value

    ReadOnlyProperty as int:
        get:
            return publicfield

    SetOnlyProperty as int:
        set:
            publicfield = value

    //a field with an automatically generated property
    [Property(MyAutoProperty)]
    _mypropertyfield as int = 5
Manuel Ceron