Thread overview
Auto-Implemented properties
Jan 05, 2013
michaelc37
Jan 05, 2013
Philippe Sigaud
Jan 05, 2013
monarch_dodra
Jan 05, 2013
michaelc37
Jan 05, 2013
michaelc37
Jan 06, 2013
Ali Çehreli
Jan 06, 2013
Ali Çehreli
Jan 06, 2013
Jacob Carlborg
Jan 06, 2013
michaelc37
January 05, 2013
i was trying to make a D template to mimic auto-implemented
properties in c#.

I think i got it to work but when i tried to give the template a
more meaning full name like AutoImplementedProperty i get a
compile error "a.title is not an lvalue".
Is this a bug?
Is there a more suitable way of doing this?

c# e.g:
class Bar
{
	public string Title { get; set; }
}

my attempt:
class Bar
{
	alias autoproperty!(string, "get", "set") title
}

template autoproperty(T, args...)
{
	import std.typetuple;
	@property
	{		
		private T _name;
		static if (args.length)
		{
			static if (staticIndexOf!("get", args) > -1)
			{
				public T autoproperty()
				{
					return _name;
				}			
			}
	
			static if (staticIndexOf!("set", args) > -1)
			{
				public void autoproperty(T value)
				{
					_name = value;
				}
			}
			
		}
	}
}

void main(string[] args)
{
	Bar a = new Bar();
	a.title = "asf";	
	writefln(a.title);

	return;
}
January 05, 2013
Hi Michael,

your code works for me (DMD 2.061, Linux), with a semicolon after the alias
in class Bar.

Also, use writeln, not writefln, because writefln assumes the first parameter is the formatting string.


January 05, 2013
On Saturday, 5 January 2013 at 22:53:44 UTC, Philippe Sigaud wrote:
> Hi Michael,
>
> your code works for me (DMD 2.061, Linux), with a semicolon after the alias
> in class Bar.
>
> Also, use writeln, not writefln, because writefln assumes the first
> parameter is the formatting string.

Why would you want get/set though when D offers property functions?

The argument of "if your public attribute becomes private, then code breaks" is invalid in D.
January 05, 2013
On Saturday, 5 January 2013 at 22:53:44 UTC, Philippe Sigaud wrote:
> Hi Michael,
>
> your code works for me (DMD 2.061, Linux), with a semicolon after the alias
> in class Bar.
>
> Also, use writeln, not writefln, because writefln assumes the first
> parameter is the formatting string.

Thanks for the tip.
Does it work for you if you rename the template to "AutoImplementedProperty"?
January 05, 2013
On Saturday, 5 January 2013 at 23:00:48 UTC, monarch_dodra wrote:
> On Saturday, 5 January 2013 at 22:53:44 UTC, Philippe Sigaud wrote:
>> Hi Michael,
>>
>> your code works for me (DMD 2.061, Linux), with a semicolon after the alias
>> in class Bar.
>>
>> Also, use writeln, not writefln, because writefln assumes the first
>> parameter is the formatting string.
>
> Why would you want get/set though when D offers property functions?
>
> The argument of "if your public attribute becomes private, then code breaks" is invalid in D.

I'm not sure if i ever would use the template, but anyway I was having a cs vs d argument with a friend, and we ended up writing code samples for comparison.

This is just one of the items that came up.
January 06, 2013
On 01/05/2013 03:25 PM, michaelc37 wrote:
> On Saturday, 5 January 2013 at 22:53:44 UTC, Philippe Sigaud wrote:
>> Hi Michael,
>>
>> your code works for me (DMD 2.061, Linux), with a semicolon after the
>> alias
>> in class Bar.
>>
>> Also, use writeln, not writefln, because writefln assumes the first
>> parameter is the formatting string.
>
> Thanks for the tip.
> Does it work for you if you rename the template to
> "AutoImplementedProperty"?

I confirm this: Any name other than the seemingly magical autoproperty causes the following errors:

  Error: a.title is not an lvalue
  Error: expression has no value

Ali
January 06, 2013
On 01/05/2013 04:32 PM, Ali Çehreli wrote:

> I confirm this: Any name other than the seemingly magical autoproperty
> causes the following errors:
>
> Error: a.title is not an lvalue
> Error: expression has no value

I retract that! :) That happens when I replace only the two "autoproperty" with "AutoImplementedProperty." There is no error when I replace all four! :)

Ali

January 06, 2013
On 2013-01-05 23:40, michaelc37 wrote:
> i was trying to make a D template to mimic auto-implemented
> properties in c#.
>
> I think i got it to work but when i tried to give the template a
> more meaning full name like AutoImplementedProperty i get a
> compile error "a.title is not an lvalue".
> Is this a bug?
> Is there a more suitable way of doing this?
>
> c# e.g:
> class Bar
> {
>      public string Title { get; set; }
> }
>
> my attempt:
> class Bar
> {
>      alias autoproperty!(string, "get", "set") title
> }
>
> template autoproperty(T, args...)
> {
>      import std.typetuple;
>      @property
>      {
>          private T _name;
>          static if (args.length)
>          {
>              static if (staticIndexOf!("get", args) > -1)
>              {
>                  public T autoproperty()
>                  {
>                      return _name;
>                  }
>              }
>
>              static if (staticIndexOf!("set", args) > -1)
>              {
>                  public void autoproperty(T value)
>                  {
>                      _name = value;
>                  }
>              }
>
>          }
>      }
> }
>
> void main(string[] args)
> {
>      Bar a = new Bar();
>      a.title = "asf";
>      writefln(a.title);
>
>      return;
> }

This won't work like you think it will. All instances of "Bar" will share the same "_name" variable.

You need to use a mixin. This pass:

void main ()
{
    Bar a = new Bar();
    a.title = "asf";

    Bar b = new Bar;
    assert(b.title == a.title);
}


-- 
/Jacob Carlborg
January 06, 2013
On Sunday, 6 January 2013 at 11:32:40 UTC, Jacob Carlborg wrote:
> On 2013-01-05 23:40, michaelc37 wrote:
>> i was trying to make a D template to mimic auto-implemented
>> properties in c#.
>>
>> I think i got it to work but when i tried to give the template a
>> more meaning full name like AutoImplementedProperty i get a
>> compile error "a.title is not an lvalue".
>> Is this a bug?
>> Is there a more suitable way of doing this?
>>
>> c# e.g:
>> class Bar
>> {
>>     public string Title { get; set; }
>> }
>>
>> my attempt:
>> class Bar
>> {
>>     alias autoproperty!(string, "get", "set") title
>> }
>>
>> template autoproperty(T, args...)
>> {
>>     import std.typetuple;
>>     @property
>>     {
>>         private T _name;
>>         static if (args.length)
>>         {
>>             static if (staticIndexOf!("get", args) > -1)
>>             {
>>                 public T autoproperty()
>>                 {
>>                     return _name;
>>                 }
>>             }
>>
>>             static if (staticIndexOf!("set", args) > -1)
>>             {
>>                 public void autoproperty(T value)
>>                 {
>>                     _name = value;
>>                 }
>>             }
>>
>>         }
>>     }
>> }
>>
>> void main(string[] args)
>> {
>>     Bar a = new Bar();
>>     a.title = "asf";
>>     writefln(a.title);
>>
>>     return;
>> }
>
> This won't work like you think it will. All instances of "Bar" will share the same "_name" variable.
>
> You need to use a mixin. This pass:
>
> void main ()
> {
>     Bar a = new Bar();
>     a.title = "asf";
>
>     Bar b = new Bar;
>     assert(b.title == a.title);
> }

Yea i realized that later, but the only fix i could come up with required me passing the property name in the template parameters, so the declaration has changed a bit.

second attempt;

class Bar
{
	public mixin autoproperty!(string, "title", "get", "set");
	public mixin autoproperty!(string, "description", "get", "set");
}

mixin template autoproperty(T, alias propertyName, args...)
{
	import std.typetuple;

	mixin("private T _" ~ propertyName ~ ";");
		
	@property
	{		
		static if (args.length)
		{
			static if (staticIndexOf!("get", args) > -1)
			{
				mixin("
				T " ~ propertyName ~ "()
				{
					return _" ~ propertyName ~ ";					
				}");
			}
	
			static if (staticIndexOf!("set", args) > -1)
			{
				mixin("
				void " ~ propertyName ~ "(T value)
				{
					_" ~ propertyName ~ " = value;
				}");
			}			
		}
	}	
}