Sorry; posted without going over the Description section. :P Again, automatic storage just rubs me the wrong way. Less magic, please.
--- Without automatic storage, there's a fairly simple way to make it visible outside the property; move the "auto value;" declaration outside and make it "T _blah;" or something. Not pretty, granted, but consistent and means we don't have to muck with traits or special syntax. It's also *obvious* where stuff is accessible from. --- struct Property(T) { T delegate() getter; void delegate(T) setter; T get() { return enforce(getter, new MissingGetterException)(); } void set(T v) { enforce(setter, new MissingSetterException)(v); } } The exceptions shouldn't need explanation. :) --- Interacting with inheritance is tricky. I think what should be done is this: class A { int foo { get; set; } } Would generate the following hidden functions: A.__property_foo_get A.__property_foo_set Then, this: { A a; auto p = &a.foo; } translates to this: { A a; Property!(int) p = { getter:&a.__property_foo_get, setter:&a.__property_foo_set}; } This should allow class implementations to add a setter to read-only properties specified in either an interface or base class. (Incidentally, the internal storage could be __property_foo_(name) or something.) As for defaults: public. Properties are usually defined for public interfaces; if it was private, you might as well just use a field. --- Again, I don't like having "set" be magical. _argptr and _arguments are bad enough as it is, please let's not add more invisibly defined magic identifiers! --- Regarding your cons: get and set mustn't be made keywords; they're too short and useful. Using in and out is actually a pretty good idea. Come to think of it... would it at all be useful to be able to expose a ref property that just exposes an underlying field? Your note regarding array properties and extension methods was one I hadn't considered. It should DEFINITELY be given thought.