Hi,
can I use generic types to create <List> for controls with OE 11.5.1?
define variable x as T60LoggClass.
x = new T60LoggClass().
x:Txt = "Test".
/* fails */ define variable a as class "System.Collections.Generic.List<T60LoggClass>".
It's a class with properties only like, the standard in C#
using Progress.Lang.*.
block-level on error undo, throw.
class T60LoggClass:
define public property IDUser as character no-undo
get.
set.
define public property Txt as character no-undo
get.
set.
end class.
Re Mike's comment on 11.6 and the ProBindingSource... Thanks for the vote of confidence, but alas, it is still a problem in 11.7. :-(
And an aside: this thread is about too many different topics!
Thanks Mike for the hint.
class T60LoggClass inherits System.Object:
define public property IDUser as character no-undo
get.
set.
define public property Txt as character no-undo
get.
set.
end class.
----------------------------------------------------------------
/* class/syntax test: */
define variable x as T60LoggClass.
x = new T60LoggClass().
x:Txt = "Test".
define variable a as "System.Collections.Generic.List<T60LoggClass>". /* compile error */
Still this error:
Multiple markers at this line - ** ..Progress\Developer Studio 4.3.1\workspace\TestProject\FormLogging.cls Could not understand line 282. (196) - Invalid substitution type 'T60LoggClass'
supplied for a type parameter of Generic class System.Collections.Generic.List. (15214) - Invalid datatype specified: System.Collections.Generic.List. Specify a datatype such as 'character' or the name of a
class. (5638)
here is a kb highlighting the issue: knowledgebase.progress.com/.../000040521
it offers apotential workaround via using a wrapper
System.Object was a good hint, now I got it running:
But, "new T60LoggClass()." is yery slow.
For each: FAST
assign List and display in Telerik grid control: FAST
But when I only add "new T60LoggClass()" to the each loop, I need to wait a few seconds.
Even when I remove every property from the class creating ~70000 times a new "empty" class takes many seconds.
class T60LoggClass inherits System.Object final:
define public property DatLog as char no-undo
get.
set.
define public property IDUser as char no-undo
get.
set.
define public property Handelse as char no-undo
get.
set.
define public property LastChanged as char no-undo
get.
set.
define public property LastUser as char no-undo
get.
set.
define public property Logg as char no-undo
get.
set.
define public property Txt as character no-undo
get.
set.
end class.
define variable rArrayList as class /* type parameter */
"System.Collections.Generic.List<System.Object>" no-undo.
rArrayList = new "System.Collections.Generic.List<System.Object>"().
define variable x as T60LoggClass.
for each T60Logg no-lock ...:
x = new T60LoggClass().
assign
x:IDUser = T60Logg.IdUser
x:Txt = T60Logg.Txt
x:DatLog = string(T60Logg.DatLog)
x:Handelse = string(T60Logg.Handelse)
x:LastChanged = string(T60Logg.LastChanged)
x:LastUser = T60Logg.LastUser
x:Logg = string(T60Logg.Logg).
rArrayList:Add(x).
end.
this-object:radGridView3:DataSource = rArrayList.
Unbelievable.
for each T60Logg no-lock where T60Logg.DatLog >= dt:
create ttT60Logg.
buffer-copy T60Logg to ttT60Logg.
end.
is 3 times faster than
for each T60Logg no-lock where T60Logg.DatLog >= dt:
x = new T60LoggClass().
end
And this class is still empty.
Yep, anything that looks like an ORM is not really feasible in OO ABL at least not atm :(
Each "NEW" is the rough equivalent of a RUN statement in terms of time, so you need to structure code like this accordingly. I'd suggest instantiating an OO structure outside of the loop and then make calls into the structure when in the loop.
PSC knows about this issue and is doubtless doing what they can about it.
But my list needs objects and a object is a class and I have no idea how to create an object without new.
BTW: Doing the same with much more objects needs <0,1 sec in C#
Or again a C# assembly, I pass a temp-table as parameter and it runs conversion into a List<objects>. (rough idea)
a) WRITE-XML/JSON the temp-table table into a LONGCHAR and pass that to the assembly.
b) Use a Progress.Data.BindingSource on a query over the TT-records. In .NET reflect the binding source to get the data
c) Inside your Assembly, use the .NET Proxy (OpenClient) and call into an AppServer routine.
Hi Mike,
thank you for the input.
This thread has to-do with https://community.progress.com/community_groups/openedge_development/f/19/t/26959.
a) I need to check whether this can be an input for the Grid
b) This "fails" with sorting within the grid and I get no SortRequest in the BindingSource (other thread)
c) no option
I have an open case at PSC/Telerik why sorting with bounded data is so slow and awaiting an outcome.
The last was about optimizing ProBindingSource.
Both in a) and b) you'll have to write .NET Assemblies. In both cases you'd have to return a .NET Array of PONO's to the Grid.
But before wasting time, I'd test this on 11.6. Progress has fixed several issues between Telerik and the ProBindignSource in 11.6.
"Each "NEW" is the rough equivalent of a RUN statement in terms of time "
O.k., using -q reduced the creation from 50000 dummy instances of a class from 5 seconds to 1,5.
Still too slow.
Re Mike's comment on 11.6 and the ProBindingSource... Thanks for the vote of confidence, but alas, it is still a problem in 11.7. :-(
And an aside: this thread is about too many different topics!
Hi All,
because the classes in package System.Collections.Generic cannot contain instances of classes that inherit from Progress.Lang.Object, I have written my own code, that enables this. The basis, of course, is a temp-table, and the code is in an include.
an implementation example:
class Example.SomeCollection:
{Example/GenericCollection.i &PackageName = "Example"
&ClassName = "SomeCollection"
&KeyPresent = "YES"
&ValueType = "Example.SomeClass"}
end class.
The include needs the packagename and the classname of the defined class. ValueType is the reference to your own class or any other classtype. Also any datatype will fit, even longchars, memptrs and raws. You can even specify an interface here. If you set KeyPresent (= character) to true, you will get a dictionarylike structure of Key-Value pairs.
If you open the preprocessor view you can view the methods/properties.
The class acts like a collection/dictionary, with methods like Add, Delete, IsEmpty, Contains, IndexOf. The class is not indexed, so you cannot use Item[n]. Instead you use the Item method, that receives a number or, if specified, a Key. It also has a built-in enumerator/iterator with methods ResetEnumerator, NextAvailable, Get{First|Next|Previous|Last}.
After a call to method Item or GetNext, you do not have to cast your object reference. It even contains the events ItemAdded and ItemDeleted to have other classes react to adding and deleting object references to the list. The event argument class is an instance of the collection class you are defining, but only with 1 instance.
It also contain the properties:
After a call to Get{First|Next|Previous|Last} these properties are set.
If you are interested you can download a working example from https://prowill.livedrive.com/. Doubleclick the "GenericExample" icon and downlaod the "Examples" folder; copy it to your workspace and run SomeClassCollectionTest.p.
Feel free to make your own adjustments
Regards,
Will
thumbs down should be Item [ n ]
|
Similar basis, how could it be an different :-), but because you have a ready-made class, you will still have to cast your references.
You're correct; didn't look any further then the List class.
I'd like to view that presentation. And I agree; it's a pity this doesn't come out-of-the-box.
Thx Mike