Cannot assign "not nullable class to object"

I am trying to create an object from a class. I have tried to make a very simple example. I am having trouble getting the code to compile.

When I try to compile the code:

namespace DSTest19;

interface

uses
System.Drawing,
System.Collections,
System.Collections.Generic,
System.Linq,
System.Windows.Forms,
System.ComponentModel;

type
///


/// Summary description for MainForm.
///

MainForm = partial class(System.Windows.Forms.Form)
private
method button1_Click(sender: System.Object; e: System.EventArgs);
protected
method Dispose(disposing: Boolean); override;
public
constructor;
end;

TMyObj = class(Object)
public
S:String;
end;

TMyClass = class of TMyObj;

TMyObjA = class(TMyObj)
public
SofA :String;
end;

TMyObjB = class(TMyObj)
public
SofB : String;
end;

implementation

{$REGION Construction and Disposition}
constructor MainForm;
begin
//
// Required for Windows Form Designer support
//
InitializeComponent();

//
// TODO: Add any constructor code after InitializeComponent call
//
end;

method MainForm.Dispose(disposing: Boolean);
begin
if disposing then begin
if assigned(components) then
components.Dispose();

//
// TODO: Add custom disposition code here
//

end;
inherited Dispose(disposing);
end;
{$ENDREGION}

method MainForm.button1_Click(sender: System.Object; e: System.EventArgs);

var LMyObj :TMyObj;
LMyClass :TMyClass;

begin
LMyClass:=TMyObjB;
LMyObj:=new LMyClass;
LMyObj.S:=‘Hello’;
(LMyObj as TMyObjB).SofB:=‘World’;
end;

end.

I get the compiler error on the line LMyObj:=new LMyClass;:

Severity Code Description Project File Line Suppression State
Error (E62) Type mismatch, cannot assign “not nullable TMyClass” to “TMyObj” DSTest19 D:\Prism\DSTest19\DSTest19\DSTest19\Main.pas 80

I cannot see what is wrong.

I have tried to replace the line:

LMyClass:=TMyObjB;

with

LMyClass:=classOf(TMyObjB);

but it makes no difference.

If somebody could give me a pointer on how to achieve this, it would most appreciated.

“class of” type are metaclasses, and not directly compatible with instances of the class they represent — so you cannot assign one to the other.

What you want, surely is

LMyClass:=TMyObjB;
LMyObj:=new LMyClass;

note the new LMyClass, not new TMyClass?

Hi Marc,

The code I posted was wrong, I probably fiddled around with it when trying to get the code to work.

I do have exactly what you suggest:

LMyClass:=TMyObjB;
LMyObj:=new LMyClass;

Can you send me the full project? thanx!

Hi Marc,

I have simplified the project to just a .net command line program, but it still shows the same problem.

Project source is in:
ObjFromClass.zip (32.0 KB)

Thanks for looking at this.

Mark,

Thanx.

This is very strange; I can’t indeed find anything wrong with this code, so this sounds like a compiler bug. I’ll log an issue and have my colleague have a look tomorrow.

What is strange is that this is about the simplest use case of class references I can think of, and it fails; yet I have code crucial for Elements, in EBuild, that uses class references and works fine. Very weird,.

My apologies for the inconvenience.

Thanks, logged as bugs://84864

Thanks Marc,

I am trying to move some code from XE3 Prism to Oxygene and this is an issue which is stopping the move. Creating an object from a class reference worked fine in the Prism code, so I know that it can work.

I do appreciate the help that you have been giving me.

Best regards
Mark.

Yeah, this definitely should work. I hope we can get either a fix or a workaround for you, this week.

bugs://84864 got closed with status fixed.

It’s good to hear that there is a fix. How do I get hold of the fixed code bearing in mind that I am on a trial license still.

Thanks

We’ll have a new build today; I will quit it in your Personal Downloads folder when ready (remind me tomorrow morning if i forget in the day’s rush ;). Also, let me know if tie need a new trial extension to make the build work…

Hello Marc,

I don’t see the new version in my personal downloads. I cannot download the new version as I am still on a trial license. Please can you send me a new trial extension as well.

Thanks
Mark

Mark,

I didn;t out it in your personal Downloads because we ended up publishing it as Stable, so you availabnkle as public download for everyone.

i’ll send you a new trial extension via PM.

—marc

Hi Marc,

The test code does now compile in 2549, but unfortunately it does not run correctly.

I have extended the code slightly and tried to access a field on the TMyObjB object which should have been created, but I get an InvalidCastException when I run the code.

I cannot see what is wrong with the code.

Best regards
Mark

bugs://84864 got reopened.

My apologies — I have reopened the issue for a further look. I’m sorry that this skipped thru our testing when fixing the original reported bug.

Hmm, could it be that your current code differs from the test case we had? that test case runs fine for me:

Can you send me the project that fails?

Hi Marc,

New code:

ObjFromClass.zip (61.9 KB)

Best regards
Mark

ah!

you need a virtual constrictor for this to work:

  TMyObj = class
  public
    S :String;
    method Caption:String; virtual;
    begin
      result:=S;
    end;
    
    constructor; virtual; empty;
  end;