Accessing the containing object in property wrappers

Hi,
I was wondering if it was possible to access the containing object

  SomeClass = public class
  public
    [MyWrappedProperty]
    property MyValue:Integer;
    property MyOtherProperty:String;
  end;

If I have the above I want to set the value of MyOtherProperty from MyWrappedProperty. I want to create a composite property that is the combination of 2 other property values.

Thanks,
John

I’m not sure I understand; can you elaborate?

I have this class

  EmployeeLink = public class
  public
    property EmployeeId:String;
    property OfficeId:String;
    property Id:String;
  end;

var empl := new EmployeeLink;
empl.EmployeeId := 'abc';
empl.OfficeId := 'def'
empl.Id := 'abc-def'

I want to assign Id whenever EmployeeId or OfficeId change

A yes. there’s a variant I didn’t document yet: if you declare the wrapper like this:

  [PropertyWrapper]
  MyWrappedProperty<T, TSelf> = public record
  public
    
    constructor(aValue: T); begin 
      ... 
    end;
    
    property Value[aSelf: TSelf]: T read ... write ...
    
  end;

then you get a Self reference of the object containing the wrapper passed in. Ifd you constrain TSelf to something that knows about Id, you can access sit, eg

  MyWrappedProperty<T, TSelf> = public record
    where TSelf is EmployeeLink
1 Like

I was able to get one working in .net but Im having problems with mac and ios. To be honest Im confused as to how the .net version is working. I thought it would complain about this

[MyCompositeWrappedProperty]

since it doesnt use the constructor or specify the generic types.

MacPropertyConsoleApplication.zip (109.6 KB)

I get

              -> Phase Resolving Bodies started.

E: Internal error: System.ArgumentNullException: Value cannot be null.
Parameter name: items
at System.Collections.Immutable.ImmutableArray1+Builder[T].AddRange (System.Collections.Generic.IEnumerable1[T] items) [0x00000] in :0
at RemObjects.Elements.Compiler.Aspects.PropertyWrapperAspect.WrapProperty (RemObjects.Oxygene.Code.Compiler.Compiler aCompiler, RemObjects.Oxygene.Code.IMutablePropertyImplementation aProperty, RemObjects.Oxygene.Code.IAttribute aAtt) [0x001e8] in <9a04485b199e4e69a5810711ceb72391>:0
at RemObjects.Elements.Compiler.PassesImplementation.WrapProperty (RemObjects.Oxygene.Code.Compiler.Compiler aCompiler, RemObjects.Oxygene.Code.IMutablePropertyImplementation aProperty, RemObjects.Oxygene.Code.IAttribute aAtt) [0x00000] in <9a04485b199e4e69a5810711ceb72391>:0
at RemObjects.Oxygene.Code.TypePropertyImplementation.get_MemberType () [0x00174] in :0
at RemObjects.Oxygene.Code.CombinedParsedType+<>c__DisplayClass14.b__2 (RemObjects.Oxygene.Code.IMemberInfo a) [0x0003e] in :0
at RemObjects.Oxygene.Code.CombinedParsedType.ForAllMembers (System.Func2[T,TResult] action) [0x0003c] in <cc2a6b31cc4d4bbf8bf2b66d8b522d83>:0 at RemObjects.Oxygene.Code.CombinedParsedType.AddCtors (System.Boolean aForce) [0x00157] in <cc2a6b31cc4d4bbf8bf2b66d8b522d83>:0 at RemObjects.Oxygene.Code.CombinedParsedType.Q () [0x010ec] in <cc2a6b31cc4d4bbf8bf2b66d8b522d83>:0 at RemObjects.Oxygene.Code.CombinedParsedType.GetMembers () [0x00009] in <cc2a6b31cc4d4bbf8bf2b66d8b522d83>:0 at RemObjects.Oxygene.Code.Compiler.ResolveMembersCompiler.ResolveType__$mapped____ (RemObjects.Oxygene.Code.Compiler.Compiler self, RemObjects.Oxygene.Code.Compiler.ScopeInfo lScope, RemObjects.Oxygene.Code.IParsedType aType) [0x00628] in <9a04485b199e4e69a5810711ceb72391>:0 at RemObjects.Oxygene.Code.Compiler.ResolveMembersCompiler+<>c__DisplayClass14.<ResolveMembers>b__4 (RemObjects.Oxygene.Code.IParsedType aType) [0x00000] in <9a04485b199e4e69a5810711ceb72391>:0 at RemObjects.Oxygene.Code.Compiler.Compiler.ForAllInternalTypes (System.Action1[T] aAt) [0x0007e] in :0
at RemObjects.Oxygene.Code.Compiler.ResolveMembersCompiler.ResolveMembers__$mapped (RemObjects.Oxygene.Code.Compiler.Compiler self) [0x00306] in <9a04485b199e4e69a5810711ceb72391>:0
E: Could not find a “Main” method in this project

Thanks, logged as bugs://85930

What do you mean? why wouldn’t this work? you dot need to specify the generics on the use, they are inferred from the property (and it’s container)…

By definition a bug; logged.

In a mac console app

  EmployeeLink = public class
  public
    [MyCompositeWrappedProperty('')]
    property EmployeId:String;
    [MyCompositeWrappedProperty('')]
    property OfficeId:String;
    property Id:String;
  end;

gives me no matching overload but it works fine in my ios app

this in my ios app

  EmployeeLink = public class
  public
    [MyCompositeWrappedProperty]
    property EmployeId:String;
    [MyCompositeWrappedProperty]
    property OfficeId:String;
    property Id:String;
  end;

gives me no matching overload.

Hm, this should give you no matching overload", as there IS no string parameter to the attribute!? Can I see the iOS test case where tis does not err?

bugs://85930 got closed with status fixed.

Thanks, logged as bugs://85944 for the string param issue

bugs://85944 got closed with status fixed.

Thanks very much, the issues here are fixed.

1 Like