Out param problem in Cocoa / WPF

IDE: _Visual Studio 2015
Version: 9.1.100.2073
Target (If relevant): Cocoa / Windows
Description:

In our dictionary class we have a TryGetValue method.

method TryGetValue(AKey: T; out AValue: U): TBoolean;

The following code:

  var value: TInteger;
  if WZones2.TryGetValue(AWZone, out value) then exit value else exit -1;

If I compile it in cocoa the compiler produces the following error:

Gravedad Código Descripción Proyecto Archivo Línea Estado de supresión
Error (E486) Parameter 3 is “nullable TInteger”, should be “out Int32”, in call to class method TDictionary<TString,Int32>.TryGetValue(&self: TDictionary<TString,Int32>; AKey: TString; out AValue: Int32): TBoolean SendaObjects.BaseLib.WPF C:\SendaObjects.BaseLib\SendaObjects.BaseLib.Sources\System\TTimeZone.pas 2227

Which forces me to put the code in Cocoa as follows:

  var value: nullable TInteger;
  if WZones2.TryGetValue(AWZone, out value) then exit value else exit -1;

However, if I now compile this code in WPF it produces the following error:

Gravedad Código Descripción Proyecto Archivo Línea Estado de supresión
Error (E486) Parameter 3 is “nullable TInteger”, should be “out Int32”, in call to class method TDictionary<TString,Int32>.TryGetValue(&self: TDictionary<TString,Int32>; AKey: TString; out AValue: Int32): TBoolean SendaObjects.BaseLib.WPF C:\SendaObjects.BaseLib\SendaObjects.BaseLib.Sources\System\TTimeZone.pas 2227

Which forces me to put the code in WPF as follows:

  var value: TInteger;
  if WZones2.TryGetValue(AWZone, out value) then exit value else exit -1;

Hahaha,
Which version of the code is correct? :confused::cold_sweat:

I think this version of Elements can not be used.

Best regards,
Jose A.

to start with:

what’s TInteger defined as?

hm, no. the message says the parameter is nullable, not that it should be. adding nullable is unlikely top be the right fix.

we’ll need a more complete test case to say more, sorry.

When using generics on cocoa and Java, a value type turns into a nullable because generics there can only hold an object. This is unfortunate but can’t be helped.

Carlo,

In the previous version everything works correctly.
The problem is only in this version.

What should be done to make the above code work on all 3 platforms without any modification?

TInteger in Toffee:
TInteger = public RemObjects.Oxygene.System.Int32;

in Echoes:
TInteger = public System.Int32;

But I do not think there’s anything to do with the problem.
In the previous version everything worked correctly.

With Sugar the same problem occurs:

method RootViewController.didReceiveMemoryWarning;
begin
  inherited didReceiveMemoryWarning;

  // Dispose of any resources that can be recreated.

  var kk := new Dictionary<String,Integer>;
  kk.Add('hello',1);
  kk.Add('hola',2);
  var v: Integer;
  if kk.TryGetValue('hello',out v) then
  begin
    var eureka := true;
  end;
end;

Gravedad Código Descripción Proyecto Archivo Línea Estado de supresión
Error (E486) Parameter 3 is “Integer”, should be “out nullable Integer”, in call to class method Sugar.Collections.Dictionary<NSString,nullable Integer>.TryGetValue(&self: Sugar.Collections.Dictionary<NSString,nullable Integer>; aKey: NSString; out aValue: nullable Integer): Boolean AppSimpleApp69 E:\Mis Archivos\Projects\SendaSoft\Oxygene\Bugs\Bugs 2016.11.26 - 2\AppSimpleApp69\AppSimpleApp69\RootViewController.pas 37

I attach project and screenshot.
Bug275.rar (265.6 KB)

Best regards,
Jose A.

I think that method used to be inline ie mapped, which does support this.

But you’ll have to correct Sugar or Elements to make it work in Cocoa, right?
What is the solution for it to work again?
This version may not be used as it is.
This is a bug, right? :wink:

It’s an unfortunate issue. But I don’t think there’s a good fix, this is because this is how generics always have worked in Elements, I can’t change that.

Carlo,
So you want to say that if we want the code to be cross-platform developers have to do this?

  var kk := new Dictionary<String,Integer>;
  kk.Add('hello',1);
  kk.Add('hola',2);
  {$IF ECHOES}
  var v: Integer;
  {$ELSE}
  var v: nullable Integer;
  {$ENDIF}
  if kk.TryGetValue('hello',out v) then
  begin
    var eureka := true;
  end;

Best regards,
Jose A.

atm yes. Until I find a good solution (which I don’t have at this point).

Ok. Thanks Carlo.

José,
you can perhaps also define a class alias (not tested, just an idea):

Type
  XInteger = {$if Echoes} Integer {$else} Nullable Integer {$endif};

Yes, it is a possibility, however, it would have to do it with all types, this kind of solutions look like a patch, but, thank you very much for your advice. :grinning: