Is it possible to step through the members of a C++ struct? - c#

I want to step through the members of a C++ struct and print out their values. I can easily code this explicitly, but is there any way of doing it without actually knowing what's in the struct?
I suppose I'm looking for a C++ equivalent of C#'s foreach command.
Thanks for any help.
ADD: I'm doing something like this in C#. This code sets the struct members from an XML file read previously:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct SettingsStruct
{
public uint nLength;
}
private void UpdateSettings()
{
SettingsStruct settings = new SettingsStruct();
foreach (FieldInfo fieldInfo in typeof(SettingsStruct).GetFields())
{
string settingName = "SETTING." + fieldInfo.Name.ToUpper();
if (appSettings.Contains(settingName))
{
switch (fieldInfo.FieldType.FullName)
{
case "System.UInt32":
fieldInfo.SetValueDirect(__makeref(settings), uint.Parse((string)appSettings[settingName]));
break;
}
}
}
}

If you are willing to use boost fusion you can do this. First "promote" this structure to a fusion sequence, and then you can iterate through the sequence printing out each member.

You could overload operator<< for your struct, then you only have to write the code once.

The following Stackoverflow answer should give you an idea on what you are looking for
Iterate Over Struct; Easily Display Struct Fields And Values In a RichEdit Box

Afraid not. C++ offers limited reflective capability. The RTTI C++ system gives you access to types, but no introspection to the fields within that type.
With some macro wizardry / hackery you might be able to achieve this, see Reflection for C++ for an example.

The foreach command does'nt do what you are saying in C#. The foreach iterates over the elements of a collection (array, set, list ...) not the members of a struct (say "length" ...).
The equivalent of foreach in C++ is to use iterators (xs.begin(), xs.end()). You can use BOOST_FOREACH to have a cleaner syntax (or for(X& s : xs) in C++1x).

C++ doesn't allow iteration over general class members. However, if you are prepared to accept some limitations, and use techniques that some will regard as pure evil, you can set up a framework to allow iteration over members of a particular family of class types. This works by abusing the fact that the default assignment operator is recursively applied to all members of a class.
First we need to declare the types to include in the iteration:
struct Visitable1;
struct Visitable2;
struct Visitable3;
We also need an abstract base class for operations to do while iterating (destructor omitted for brevity; for safety, it should be either virtual or protected):
struct Visitor
{
virtual void visit(Visitable1 &) = 0;
virtual void visit(Visitable2 &) = 0;
virtual void visit(Visitable3 &) = 0;
static Visitor * current;
};
and a base class (using the "curiously recursive template" idiom) for the types we can include in the iteration; this is where the operator abuse happens, modifying the behaviour of self-assignment:
template <typename T>
struct Visitable
{
void operator=(Visitable const & other)
{
if (&other == this) {
Visitor::current->visit(static_cast<T&>(*this));
}
}
};
struct Visitable1 : Visitable<Visitable1> { /* some stuff */ };
struct Visitable2 : Visitable<Visitable2> { /* some stuff */ };
struct Visitable3 : Visitable<Visitable3> { /* some stuff */ };
Finally, we can define the iteration itself:
template <class T, class Visitor>
void for_each(T & t, Visitor v)
{
Visitor::current = &v;
t = t;
}
This does have some notable shortcomings:
The "visit" functions are virtual, and so can't be generic. I can't currently think of a way to allow the use of different Visitor classes without an abstract base class. As a consequence, the iteration can only be applied to a predeclared set of types.
The use of a static variable (Visitor::current) means that only one iteration can be in progress at any time, giving thread-safety and reentrancy issues. I can't currently think of a better way to pass state to operator=, since this only works when overloading the default operator=, with a single argument of the same type as the assignee.
You may be lynched if anyone catches you writing code like this.
See codepad.org for a demonstration.

Related

How to declare a custom alias for System.Int32[] in c# [duplicate]

I'm trying to do some serialization / deserialization stuff with a custom exception type. This type has a field defined as:
private object[] resourceMessageParams;
I've got all nice and strongly typed code with some Linq expression magic, but I want to go even further than that and do something like this:
using ResourceMessageParamsType = object[];//<-- "Identifier expected" error here
/*...*/
private ResourceMessageParamsType resourceMessageParams;
/*...*/
this.resourceMessageParams =
(ResourceMessageParamsType)serializationInfo.GetValue(
ReflectionHelper.GetPropertyNameFromExpression(() =>
resourceMessageParams), typeof(ResourceMessageParamsType));
Instead of this:
(object[])serializationInfo.GetValue(
ReflectionHelper.GetPropertyNameFromExpression(() =>
resourceMessageParams), typeof(object[]));
To accomodate for possible change of type of this field in the future, so one will have to change the type only once in alias definition. However, the compiler stops at object in using ResourceMessageType = object[]; complaining that an identifier is expected. Changing to Object[] helps somewhat, but this time the bracket is highlighted with the same error message.
Is there a way to define an alias for array type in c#?
You could define a class (or struct) called ResourceMessageParamsType and define implicit operators for casting to and from object[].
struct ResourceMessageParamsType
{
private object[] value;
private ResourceMessageParamsType(object[] value)
{
this.value = value;
}
public static implicit operator object[](ResourceMessageParamsType t)
{
return t.value;
}
public static implicit operator ResourceMessageParamsType(object[] value)
{
return new ResourceMessageParamsType(value);
}
}
Simply put, you can't "alias" array types.
You can work around it by encapsulating things in a struct, but that doesn't answer your question.
Update:
From the ECMA standard,
using-alias-directive:
using identifier = namespace-or-type-name ;
which clearly doesn't say anything about arrays being permitted.
(See page 100 for how namespace-or-type-name is defined.)
I would just derive my type from System.Array. If I'm interpreting this correctly What you are describing is a non-OO approach like you would use in plain C.
Update- I guess you can't subclass System.Array. Maybe there is a way around it.
using ResourceMessageParamsType = System.Array;
Not that I pretend to understand how this "safeguard[s] serialization code against possible changes in class definition" for you.
Interfaces would be a cleaner approach, and have you considered generics?
IMO Comprehensive Unit tests will ensure that if someone changes the aliased type, that all deserialization code still works.
Wrapping in a managed struct as user541686 rightly mentions, creates another level of indirection to what is ultimately still a managed array. You can alternatively use a fixed buffer in an unsafe struct to have it allocated all-in-one under your preferred typename:
public unsafe struct MyPreferredTypeName
{
public fixed int buffer[256];
//Further dereferencing not req'd: this memory is allocated inline in the struct.
}
However you then have no choice but to use unsafe blocks in your code that uses the struct (and if I recall correctly, also fixed blocks depending on your version of C#, I think < 9.0).
public void MyMethod(MyPreferredTypeName data) //you can alternatively use unsafe in this line
{
unsafe
{
fixed (MyPreferredTypeName* dataPtr = data)
{
dataPtr[6] = 79; //etc
}
}
}

Function pointer translation from C++ to C#

I was translating some C++ code to C# and there was a function pointer within a structure definition, say func*
This func* was a pointer to a lot of other function pointers all contained within a C++ header file (This header file won't be translated).
Is there a way to translate this?
Code snippet:
struct CK_FUNCTION_LIST {
int version;
/* Pile all the function pointers into it. */
#include "pkcs11f.h"
};
The class which I wish to translate contained a member of typeCK_FUNC_LIST*.
To demonstrate what you usually do when you want to use the equivalent of function pointers in C#, take a look at this:
struct MyFunctions {
public Func<int,string,bool> ptr1;
public Action<int> ptr2;
}
class Program
{
static void Main(string[] args)
{
MyFunctions sample = new MyFunctions() { ptr1 = TestValues, ptr2 = DoThing };
sample.ptr1(42, "Answer");
sample.ptr2(100);
}
static bool TestValues(int a, string b)
{
Console.WriteLine("{0} {1}", a, b);
return false;
}
static void DoThing(int a)
{
Console.WriteLine("{0}", a);
}
}
The output is:
42 Answer
100
If you are porting the code, you have a couple of options in C#:
1) Use lamdas (e.g. unnamed delegates). If these are 1-off functions (e.g. they are only used once), this will be the best choice.
2) Use named delegates. These will behave very similarly to C++ function pointers. If you are using the same functions in several places, this will be the better choice.
Just for clarification (as Ben Voigt pointed out): these are effectively the same thing as the lamda syntax will create a delegate for you.
The delegate type can be framework-provided (Action, Func, Predicate)
or user-declared, and the delegate can be created inline (lambda,
anonymous delegate) or by naming a method.
The normal way of using function pointers in C# is to declare an Action or Func. These are type safe, so they will only accept methods matching the signature of the type arguments.
Delegates are more generic (Action and Func are just specific named ones) but less clear. Really, we'd need more information to be any more specific.

Is it possible to alias array type in c#?

I'm trying to do some serialization / deserialization stuff with a custom exception type. This type has a field defined as:
private object[] resourceMessageParams;
I've got all nice and strongly typed code with some Linq expression magic, but I want to go even further than that and do something like this:
using ResourceMessageParamsType = object[];//<-- "Identifier expected" error here
/*...*/
private ResourceMessageParamsType resourceMessageParams;
/*...*/
this.resourceMessageParams =
(ResourceMessageParamsType)serializationInfo.GetValue(
ReflectionHelper.GetPropertyNameFromExpression(() =>
resourceMessageParams), typeof(ResourceMessageParamsType));
Instead of this:
(object[])serializationInfo.GetValue(
ReflectionHelper.GetPropertyNameFromExpression(() =>
resourceMessageParams), typeof(object[]));
To accomodate for possible change of type of this field in the future, so one will have to change the type only once in alias definition. However, the compiler stops at object in using ResourceMessageType = object[]; complaining that an identifier is expected. Changing to Object[] helps somewhat, but this time the bracket is highlighted with the same error message.
Is there a way to define an alias for array type in c#?
You could define a class (or struct) called ResourceMessageParamsType and define implicit operators for casting to and from object[].
struct ResourceMessageParamsType
{
private object[] value;
private ResourceMessageParamsType(object[] value)
{
this.value = value;
}
public static implicit operator object[](ResourceMessageParamsType t)
{
return t.value;
}
public static implicit operator ResourceMessageParamsType(object[] value)
{
return new ResourceMessageParamsType(value);
}
}
Simply put, you can't "alias" array types.
You can work around it by encapsulating things in a struct, but that doesn't answer your question.
Update:
From the ECMA standard,
using-alias-directive:
using identifier = namespace-or-type-name ;
which clearly doesn't say anything about arrays being permitted.
(See page 100 for how namespace-or-type-name is defined.)
I would just derive my type from System.Array. If I'm interpreting this correctly What you are describing is a non-OO approach like you would use in plain C.
Update- I guess you can't subclass System.Array. Maybe there is a way around it.
using ResourceMessageParamsType = System.Array;
Not that I pretend to understand how this "safeguard[s] serialization code against possible changes in class definition" for you.
Interfaces would be a cleaner approach, and have you considered generics?
IMO Comprehensive Unit tests will ensure that if someone changes the aliased type, that all deserialization code still works.
Wrapping in a managed struct as user541686 rightly mentions, creates another level of indirection to what is ultimately still a managed array. You can alternatively use a fixed buffer in an unsafe struct to have it allocated all-in-one under your preferred typename:
public unsafe struct MyPreferredTypeName
{
public fixed int buffer[256];
//Further dereferencing not req'd: this memory is allocated inline in the struct.
}
However you then have no choice but to use unsafe blocks in your code that uses the struct (and if I recall correctly, also fixed blocks depending on your version of C#, I think < 9.0).
public void MyMethod(MyPreferredTypeName data) //you can alternatively use unsafe in this line
{
unsafe
{
fixed (MyPreferredTypeName* dataPtr = data)
{
dataPtr[6] = 79; //etc
}
}
}

Practical differences between classes and structs in .net (not conceptual)?

Whenever I tried to search about differences between classes and structs in C# or .net, I ended up with the conceptual overview of the two things like value type or the reference type, where the variables are allocated etc. But I need some practical differences. I have found some like different behavior of assignment operator, having constructors etc. Can anybody provide some more practical differences which will be directly useful while coding? Like the things works with one but not with other or same operation showing different behavior. And some common mistakes regarding these two.
Also please suggest where to consider using a struct instead of a class. And where the structs should not be used.
Edit:
Do I have to call the constructor explicitly or just declaring a struct type variable will suffice?(Should I make it a new question?)
OK, here are a few specific, practical differences:
A variable can be null if it’s a class, but is never null if it’s a struct.
default(T) is null for a class, but for a struct actually constructs a value (consisting of lots of binary zeros).
A struct can be made nullable by using Nullable<T> or T?. A class cannot be used for the T in Nullable<T> or T?.
A struct always has a public default constructor (a constructor with zero parameters). The programmer cannot override this constructor with a custom implementation — it is basically “set in stone”. A class allows the programmer to have no default constructor (or a private one).
The fields in a class can have default values declared on them. In a struct they can’t.
A class can inherit from another class, but a struct cannot be declared to derive from anything (it implicitly derives from System.ValueType).
It makes sense to use a class in object.ReferenceEquals(), but using a struct variable will always yield false.
It makes sense to use a class in a lock() statement, but using a struct variable will cause very subtle failure. The code will not be locked.
On a 32-bit system, you can theoretically allocate an array of up to 536,870,912 references to a class, but for a struct you need to take the size of the struct into account because you are allocating actual instances.
Structs in a container can only be modified if the container is a built-in array:
struct Point { public int x, y; void Move(int dx, int dy) { x += dx; y += dy; } }
...
Point[] points = getPointsArray();
points[0].Move(10, 0) = 10;
// points[0].x is now 10 higher.
List<Point> points = getPointsList();
points[0].Move(10, 0);
// No error, but points[0].x hasn't changed.
For this reason, I strongly favour immutable structs:
Point Move(int dx, int dy) { return new Point(x + dx, y + dy); }
...
points[0] = points[0].Move(10, 0); // Always works.
General observation: classes are usually better. Structs excel when you want to hold small, conceptually atomic data structures such as Point, Complex (number), Rational, etc.
structs, as they are value types, are copied on assignment; if you create your own struct, you should make it immutable, see Why are mutable structs evil?
Sometimes you don't want what you're passing to be mutable, and since a mutable struct may just be pure evil, I'd steer clear of ever creating one :) Here's an example a situation:
class Version:
class AccountInfo {
public string OwnerName { get; set; }
public string AccountNumber { get; set; }
}
struct Version:
struct AccountInfo {
public string OwnerName;
public string AccountNumber;
}
Now picture you called a method like this:
public bool TransferMoney(AccountInfo from, AccountInfo to, decimal amount)
{
if(!IsAuthorized(from)) return false;
//Transfer money
}
A struct is a Value type, meaning a copy gets passed into the method. The class version means a reference gets passed into the method, you wouldn't want for example the account number to be changeable after the authorization passed, you want nothing to be changed in an operation like this...you want an immutable value type. There's another question here asking why mutable structs are evil...any operation where you wouldn't want anything affected by the reference object changing, would be a practical place where a struct may fit better.
The example above may be somewhat silly, but the point is any sensitive operation where the passed in data shouldn't change in another thread or by any means really would be a place you look at passing by value.
Where they are allocated (heap vs. stack) is not something you really care about while you use them (not that you should disregard this - you should by all means study the differences and understand them).
But the most important practical difference you will come across the first time you decide to replace your class with a struct, is that structs are passed by value, while class instances are passed by reference.
This means that when you pass a struct to a method, a copy of its properties is created (a shallow copy) and your method actually gets a different copy than the one you had outside the method. When you pass an instance of a class, only a reference to the same place in memory is passed to the method, and your method is then dealing with exactly the same data.
For example, if you have a struct named MyStruct, and a class named MyClass, and you pass them to this method:
void DoSomething(MyStruct str, MyClass cls)
{
// this will change the copy of str, but changes
// will not be made to the outside struct
str.Something = str.Something + 1;
// this will change the actual class outside
// the method, because cls points to the
// same instance in memory
cls.Something = cls.Something + 1;
}
when the method ends, your class' property will be incremented, but your struct's property will remain unchanged, because str variable inside the DoSomething method does not point to the same place in memory.
The singularly important practical difference is that structs are value types, whereas classes are reference types. That has a few implications.
First of all, structs are copied on assignment. These two code blocks will have a different result (please note, normally you should neither use public fields nor mutable structs, I'm doing this for demonstration purposes only):
struct X
{
public int ID;
public string Name;
}
X x1 = new X { ID = 1, Name = "Foo" };
X x2 = x1;
x2.Name = "Bar";
Console.WriteLine(x1.Name); // Will print "Foo"
class Y
{
public int ID;
public string Name;
}
Y y1 = new Y { ID = 2, Name = "Bar" };
Y y2 = y1;
y2.Name = "Baz";
Console.WriteLine(y1.Name); // Will print "Baz"
X and Y are exactly the same, except that X is a struct. The results of this are different because every time we assign an X, a copy is made, and if we change the copy then we aren't changing the original. On the other hand, when we assign the contents of y1 to y2, all we've done is copied a reference; both y1 and y2 refer to physically the same object in memory.
The second consequence of structs being value types is generic constraints. If you want to pass in value types, the name of the constraint is literally "struct" or "class":
public class MyGeneric<T>
where T : struct
{ ... }
The above will let you create a MyGeneric<int> or MyGeneric<X>, but not a MyGeneric<Y>. On the other hand, if we change it to where T : struct, we're no longer allowed to create either of the first two, but MyGeneric<Y> is okay.
Last but not least, you need to use structs when writing interop, because with structs you're able to guarantee a specific arrangement in memory.
The link Tejs provided (http://www.jaggersoft.com/pubs/StructsVsClasses.htm) is a good explanation (although it is a bit out of date, particularly on the explanation of events).
The most import practical difference is that a struct is a value type, meaning it is passed by value rather than by reference. What this really means is that when a struct is passed as an argument, it is actually passed by copy. As a result, operations on one instance of a struct do not affect other instances.
Consider the following code:
struct NumberStruct
{
public int Value;
}
class NumberClass
{
public int Value = 0;
}
class Test
{
static void Main()
{
NumberStruct ns1 = new NumberStruct();
NumberStruct ns2 = ns1;
ns2.Value = 42;
NumberClass nc1 = new NumberClass();
NumberClass nc2 = nc1;
nc2.Value = 42;
Console.WriteLine("Struct: {0}, {1}", ns1.Value, ns2.Value);
Console.WriteLine("Class: {0}, {1}", nc1.Value, nc2.Value);
}
}
Because both ns1 and ns2 are of the NumberStruct value type, they each have their own storage location, so the assignment of ns2.Number does not affect the value of ns1.Number. However, because nc1 and nc2 are both reference types, the assignment of nc2.Number does affect the value of nc1.Number because they both contain the same reference.
[Disclaimer: The above code and text taken from Sams Teach Yourself Visual C# 2010 in 24 Hours]
Also, as others have already pointed out, structs should always be immutable. (Yes, in this example the struct is mutable but it was to illustrate the point.) Part of that means that structs should not contain public fields.
Since structs are value types, you cannot inherit from a struct. You also cannot derive a struct from a base class. (A struct can implement interfaces, however.)
A struct is also not allowed to have an explicitly declared public default (parameterless) contstructor. Any additional constructors you declare must completely initialize all of the struct fields. Structs also cannot have an explicitly declared destructor.
Since structs are value types, they shouldn't implement IDisposable and shouldn't contain unmanaged code.
Here's an interesting link: http://www.jaggersoft.com/pubs/StructsVsClasses.htm
For the most part though, there isn't much of a compelling reason to use structs when classes offer far more to the developer.

Is it possible to implement properties in languages other than C#?

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?
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
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; }
};
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.
Delphi, from which C# is derived, has had properties from the word go. And the word go was about 15 years ago.
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
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.
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;
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
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.
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 :)
ActionScript 3 (javascript on steroids) has get/set syntax also
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.
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;
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.
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
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 behaviour. Ruby already requires everything to go through.
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);

Categories

Resources