xsharp.eu • Why does the generic version of ArrayCreate require a parameterless constructor?
Page 1 of 1

Why does the generic version of ArrayCreate require a parameterless constructor?

Posted: Fri Oct 01, 2021 11:07 am
by leon-ts
Hi,

There is the following code:

Code: Select all

LOCAL a AS ARRAY OF MyClass
a := ArrayCreate<MyClass>(10)
MyClass:

Code: Select all

CLASS MyClass
    CONSTRUCTOR(oSomeParam AS OBJECT) STRICT
END CLASS
Compiling this code returns an error:
XS0310 'MyClass' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'XSharp.RT.Functions.ArrayCreate<T>(dword)'
Why does the generic version of ArrayCreate require a parameterless constructor?
According to the documentation, the ArrayCreate function сreates an uninitialized, one-dimensional array. In the non-generic version, the array is filled with NIL. In the generic version, these should be NULL values. There is no need to create instances of the class.

For example, this code is similar to the following (which compiles without errors):

Code: Select all

LOCAL a AS MyClass[]
a := MyClass[]{ 10 }
Best regards,
Leonid

Why does the generic version of ArrayCreate require a parameterless constructor?

Posted: Fri Oct 01, 2021 11:17 am
by robert
Leonid,

To Support AAdd() and ADel() we need to create new items at the end of the array. These are created by calling the default constructor of the type.

Robert

Why does the generic version of ArrayCreate require a parameterless constructor?

Posted: Fri Oct 01, 2021 11:27 am
by leon-ts
Robert,

To be honest, I didn't quite understand why this is needed, including in the AAdd and ADel functions. The AAdd function adds an element that I myself explicitly pass into it. And ADel offsets the array and the last element must be NULL. That is, in both functions, the functions themselves, it seems, should not create anything.

P.S. Perhaps I'll take a look at the X # Runtime. Maybe then it will become clear to me what this is for.

Best regards,
Leonid

Why does the generic version of ArrayCreate require a parameterless constructor?

Posted: Fri Oct 01, 2021 11:46 am
by robert
Leonid,
I made a mistake. I meant the ASize() that may add empty elements.
But now that I think of it we can change it and simply insert NULL in the base class and NIL in the subclass.
I'll make that change.

Robert

Why does the generic version of ArrayCreate require a parameterless constructor?

Posted: Fri Oct 01, 2021 11:47 am
by leon-ts
Robert,

I looked into the X# Runtime. For the AAdd function, I saw no problem for classes without parameterless constructor. There, the ready element specified by the calling code is simply added to the List class.

As for the ADel function, it uses DEFAULT(T) for the last element of the array. It seems to me that this works for value types, but not for reference types (classes). Indeed, according to the logic of arrays in VO, where they came from, in such cases there should be uninitialized values. For value types, this is indeed DEFAULT(T), but for reference types, it is NULL.

Best regards,
Leonid

Why does the generic version of ArrayCreate require a parameterless constructor?

Posted: Fri Oct 01, 2021 12:34 pm
by leon-ts
Robert,

I'm sorry, I made a mistake too :)
DEFAULT(T) returns NULL for reference types.

Best regards,
Leonid

Why does the generic version of ArrayCreate require a parameterless constructor?

Posted: Fri Oct 01, 2021 1:22 pm
by robert
Leonid,
The problem is in the functions not in the class.
In a previous release I have removed the constraint from the ArrayBase class but forgot to remove the constraints from the related functions.

For now replace the call to

Code: Select all

ArrayCreate<MyClass>(10)

with

Code: Select all

LOCAL a AS ARRAY OF MyClass
__ArrayBase<MyClass>{10,TRUE}
That should work.

Or create your own version of ArrayCreate<T>

Code: Select all

FUNCTION ArrayCreate<T>(dwElements AS DWORD) AS __ArrayBase<T> 
    RETURN __ArrayBase<T>{dwElements,TRUE}


Robert

Why does the generic version of ArrayCreate require a parameterless constructor?

Posted: Fri Oct 01, 2021 1:31 pm
by leon-ts
Robert,
Yes, indeed, now I have seen: WHERE T IS NEW()

Thanks for the solution!
For now, I will use the variant with

Code: Select all

__ArrayBase<MyClass>{10,TRUE}
and put TODO, so that in one of the future versions (where, I believe, you will fix it), return the original code.

Best regards,
Leonid

Why does the generic version of ArrayCreate require a parameterless constructor?

Posted: Fri Oct 01, 2021 3:32 pm
by Chris
Leonid, Robert has already fixed that now :)

.

Why does the generic version of ArrayCreate require a parameterless constructor?

Posted: Fri Oct 01, 2021 3:38 pm
by leon-ts
Chris, great! :)

Best regards,
Leonid