C # dışındaki dillerde özelliklerini uygulamak mümkün mü?

17 Cevap

Son zamanlarda C # ve WPF bir kriz sırasında, C # 'ın özellikleri gibi var:

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

Length_metres bir özellik için bir alan olmaktan değişebilir ki, elbette, farkeden ve kod bakım gerekmez. WPF de çok mutlu nesne özelliklerini UI öğeleri bağlayabilirsiniz.

Ben ilk sınıflar ve nesneler hakkında öğrendim, ben çok açık görünüyordu, çünkü bunu yapmak için bir yol vardı ki kabul! Bir sınıf içinde karmaşıklığı gizleme nokta daha fazla depolanan ne umurumda gerek kalmamasıdır. Ama bunu görmek için şimdiye kadar almıştır.

Eğlenceli, Ben ilk VB.Net yapılan gördüm. OO saflık bu ön kenarı.

Soru, javascript, python, php gibi, ben daha sık kullanan diğer dillerde özelliklerini yeniden olabilir mi? Ben bir kapağın bir değişken ayarlamak eğer javascript, ben doğrusu bunun sonucunda daha, tekrar kapatılması almazsınız?

17 Cevap

Python kesinlikle özelliklerini destekler:

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 başlayarak, sözdizimsel şeker salt okunur özellikleri var ve 2.6, yazılabilir olanlar da:

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

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

C # özellikleri çoğunlukla sadece bir derleyici özelliği vardır. Derleyici özel yöntemler get_PropertyName ve set_PropertyName oluşturur ve benzeri aramaları ve dışarı çalışır. Ayrıca yöntemlerin specialname IL özelliği.

Seçtiğiniz dil önişlemci çeşit destekliyorsa, benzer bir şey uygulayabilirsiniz ama aksi takdirde oldukça fazla ne var ile sıkışmış demektir.

Kendi. NET dili uygulanması eğer Ve tabii ki, C # derleyicisi de yok ne yapabilirim.

Nedeniyle uygulama ayrıntıları için, alanlar ve özellikler arasındaki ince farklılıklar aslında vardır. Ayrıntılar için this question bakın.

C # türediği Delphi, kelime özelliklerini gitmek olmuştur. Ve kelime gitmek yaklaşık 15 yıl önceydi.

En dinamik diller böyle bir şey destekleyecek. Smalltalk ve Ruby, alanları doğrudan maruz değil - onlara ulaşmak için tek yol bir yöntem geçer. Diğer bir deyişle - Tüm değişkenler şahsidir. Yakut daha basit tip yapmak için bazı makro (sınıf yöntemleri gerçekten) vardır:

class Thing
  attr_accessor :length_inches
end

length_inches için bir alıcı ve bir ayarlayıcı yapacaktır. Perde arkasında, sadece bu üreten bulunuyor:

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

(Ruby crash-kursu: @ önek bir örnek değişken demektir return Ruby örtülü t.length_inches = 42 otomatik olarak çağırmak length_inches=(42) olacaktır.. t bir Thingy ise.)

Daha sonra alıcılar / ayarlayıcıları bazı mantık koymak istiyorsanız, sadece elle aynı yöntemleri uygulayabilirsiniz:

class Thing
  def length_inches
    @length_metres * 39.0
  end
  def length_inches=(value)
    @length_metres = value / 39.0
  end
end

VB kutusuna (ki, değil VB.net VB 6.0 bulunuyor) ve VBScript dışarı!

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

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

Ayrıca mümkün sahte oldukça güzel PHP adlandırma kuralları, korumalı üyeleri ve sihirli işlevleri ile birlikte uzanan bir sınıf oluşturmak için. Yuch.

Delphi arayüzleri de kullanılabilir (belirleyici ve alıcı yöntemleri ile birlikte) bir özellik modeli vardır. "Yayımlanan" görünürlük özellikleri de IDE nesne denetçisinde görüntülenir.

Bir özelliği olan bir sınıf tanımı aşağıdaki gibi olacaktır:

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

public
  property Bar: string read GetBar write SetBar;

end;

veya (Setter / Getter olmadan):

TFoo = class
private
  FBar: string;

public
  property Bar: string read FBar write FBar;

end;

Ben bu Python eşdeğer olduğunu düşünüyorum

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 )

Bu gibi çalışır.

>>> l=Length(2)
>>> l.metres
2
>>> l.inches
78.0
>>> l.inches=47
>>> l.metres
1.2051282051282051

Objective-C 2.0 / Kakao:

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

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

@end

Sonra uygulanmasında, sadece belirtin:

@synthesize myInt, myString;

Bu gibi uyumlu adlandırma kuralları anahtar-değer-kodlama ile bu üye değişkeni için erişimciler oluşturur:

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

Lütfen erişimcilere yazarak bir sürü iş kaydeder.

Bu diğer dillerde özelliklerini uygulamak kesinlikle mümkün. VB ve örneğin F # açık özellik desteği var. Ancak bu iki özellik desteği vardır CLR hedef.

VB.

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

Ben javascript inanmıyorum veya PHP özellik sözdizimi destekler ama bu dillerde çok aşina değilim. Bu özelliklerini simüle hemen hemen her dilde alan get / set erişim yöntemlerinin oluşturmak mümkündür.

Kaputun altında,. Net özellikleri gerçekten sadece / set yöntemleri almak için aşağı sonuçlanır. Onlar sadece gerçekten güzel bir sarıcı var :)

Ne yazık ki, ben henüz kendim denemedim, ama olsun sihirli yöntemler set ve __ __ yoluyla PHP özelliklerini uygulamak mümkün olduğunu okudum. İşte blog post bu konuda bulunuyor.

ActionScript 3 (steroid javascript) da / set sözdizimi almak etti

Sen PHP5 magic functions ile bunun gibi bir şey yapabilirsiniz.

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;

Sen sözdizimsel şeker ve büyü değişen derecelerde, tüm dillerde türlü bunu yapabilirdi. Önce bahsedildiği gibi Python, bunun için destek sağlar (ve kesinlikle daha o kadar temiz olabilir dekoratörler kullanarak). PHP uygun __ get () ve __ seti () yöntemi (Perl ile çalışıyorsanız., Sen davranışını çoğaltmak için bazı kaynak filtreleri kullanabilirsiniz muhtemelen bazı yönlendirme ile makul bir faks sağlayabilir. Ruby zaten geçmesi için her şeyi gerektirir

Ben ilk Visual Basic (gibi, sürüm 1 ya da bir şey) ile oynadığı zaman ben yaptım ilk şey C + + özelliklerini yeniden deneyin oldu. Şablonlar anda benim için kullanılabilir, ama muhtemelen daha önce şimdi gibi bir şey olurdu:

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

Aşırı çözünürlüğü ile, etkin fonksiyon adının bir parçası olarak hareket etmek, sadece var - "anahtarı" parametresi get_property / set_property ve uygulamaları göz ardı unutmayın.

Şimdi my_class çiğ alanları sanki birçok durumda kamu üyeleri first_name ve limbs başvurmak mümkün olabilir, ama onlar sadece bir sağlayacak kullanıcı gelen get_property / set_property üye işlevleri çağırmak için alternatif sözdizimi.

Eğer derleyici gerekli türü dönüştürme anlaması mümkün olduğunda, değeri almak için bir özellik () değeri aramak olurdu bazı durumlar vardır, çünkü mükemmel değil. Ayrıca kurucusuna üyelerine this geçmesiyle bir uyarı alabilirsiniz, ancak bu durumda o sessizlik olabilir.

Boo Python çok benzer bir. NET dili olduğunu, ancak statik yazarak. Bu özelliklerini uygulayabilirsiniz:

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

Kongre bir get_PropertyName() uygulamak ve bir set_PropertyName() yöntemi (o da CLR tüm özelliklerini VB.NET / C # sadece sözdizimsel şeker vardır -. Olan neden alanında mülkiyet veya tersi kırma ve yeniden derlemek için istemci kodu gerektirir değiştirin.

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