Jump to content
Lars Fosdal

Generics: Classes vs Records - Differences in use

Recommended Posts

Thread split off from

if Data.TryGetValue(aId, vNewData)
then vNewData.DataName := aName;
else begin
  vNewData := TDataRec.Create;
  vNewData.DataId := aId;
  vNewData.DataName := aName;
  Data.Add(aId, vNewData);
end;

 

@Stefan Glienke - What is the best container for random lookup access for records?

  • Like 1

Share this post


Link to post
1 hour ago, Lars Fosdal said:

but I don't use them with records, only objects

Why not?

 

1 hour ago, Lars Fosdal said:

What is the best container for random lookup access for records?

Surely the answer is the same as for objects. If you use a dictionary for objects, why not a dictionary for records?

Edited by David Heffernan

Share this post


Link to post

It depends on how you want to access the data. This isn't really related to associate array style access by key. The issues with value types and copying apply equally to all containers.

 

Share this post


Link to post

Which is why I don't use dictionaries with records. It is rare that I load up a dictionary and do not need to change some of the content later.
If I was insistent on doing records, I would probably write code that ordered the array by the key and did binary lookup to a pointer to the record.

Share this post


Link to post
32 minutes ago, Lars Fosdal said:

Which is why I don't use dictionaries with records. It is rare that I load up a dictionary and do not need to change some of the content later.
If I was insistent on doing records, I would probably write code that ordered the array by the key and did binary lookup to a pointer to the record.

How is it any different from holding them in TList<T>?

  • Like 1

Share this post


Link to post
5 minutes ago, Lars Fosdal said:

TList<^TDataRec>? 

Really? How are the records allocated? And if you could do that, why couldn't you do exactly the same with a dictionary.

 

Which is my original point. If you can't use a dictionary with records, then I don't see that you can use any collection with records.

Edited by David Heffernan
  • Like 1

Share this post


Link to post
1 hour ago, Lars Fosdal said:

What is the best container for random lookup access for records?

That would very much depend on the criteria by whom they are looked up, if that criteria changes and how often elements are added/removed don't you think?

  • Like 1

Share this post


Link to post

I agree. If we consider the current example, what would be your choice? 

Share this post


Link to post
5 minutes ago, Lars Fosdal said:

I agree. If we consider the current example, what would be your choice? 

image.jpeg.7973a3b8211323fc87ad37d1870ecc23.jpeg

(not enough information to give an informed suggestion) - anyhow that was not the question of this topic - as a mod/admin you should not contribute to totally derailing threads 😉

Edited by Stefan Glienke

Share this post


Link to post

Another benefit of using generic classes over records is the amount of reuse.

Share this post


Link to post
1 hour ago, Lars Fosdal said:

Another benefit of using generic classes over records is the amount of reuse.

You can use records and classes with generics.

Share this post


Link to post
3 hours ago, David Heffernan said:

You can use records and classes with generics.

Start a new topic.

Give some examples.

Share this post


Link to post
2 hours ago, Lars Fosdal said:

Start a new topic.

Give some examples.

We don't need a topic or any examples. We all know that records can be used as generic types. 

  • Like 1

Share this post


Link to post
On 9/10/2020 at 9:35 PM, David Heffernan said:

We don't need a topic or any examples. We all know that records can be used as generic types. 

We also know that the two need to be handled differently when it comes to changing their contents.

Share this post


Link to post
1 hour ago, Lars Fosdal said:

We also know that the two need to be handled differently when it comes to changing their contents.

That is correct. But that's not the point you made.

Share this post


Link to post
32 minutes ago, David Heffernan said:

That is correct. But that's not the point you made.

"the amount of reuse" was my point. 

Share this post


Link to post

I am trying to improve my tendency to spin off a discussion in a thread focused on something else, so here we are.

 

To reiterate, my preference for classes over records with regards to generics, is that read-only generics for records works perfectly for its use, but when you need to update the content in the record, it becomes a very different exercise.

 

You either need to have structure specific methods to change the record field values, or you must copy the entire record, modify it, and the copy it back.

The first option wreaks havoc on reuse, and the second option can become a performance bottleneck if the record is large. Even more so, if the record is multidimensional, containing records with arrays of records.

 

The same kind of change in a multidimensional class, is trivial in comparison.

 

@David Heffernan - hence my "the amount of reuse" argument.

Share this post


Link to post

My number one argument for constraining on class in a generic type argument when possible is that you then can build most of the generic in a non generic layer and just put a small generic layer on top. That makes for less bloat.

  • Like 1

Share this post


Link to post
27 minutes ago, Lars Fosdal said:

you must copy the entire record, modify it, and the copy it back

Not if you use a collection that provides you access to items via references to the underlying records

  • Like 1

Share this post


Link to post
10 minutes ago, David Heffernan said:

Not if you use a collection that provides you access to items via references to the underlying records

Can you offer an example?

Share this post


Link to post

 

6 minutes ago, Lars Fosdal said:

Can you offer an example?

TList<T>

 

FWIW my codebase doesn't use the RTL generic collections. It uses a collections library that I wrote, that amongst other things has collection classes that allow access to items via references to the underlying records for exactly this situation.

 

I think that you are making valid points, but you aren't pinning the blame in quite the right place. I don't think the issue is with value types per se. To my mind the issues are more about limitations of the standard RTL collection classes.

Edited by David Heffernan
  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×