When and why use anonymous class instead of stucts for simple objects - class

I read in this answer A generic list of anonymous class how to load a list with anonymous class objects. My question is why and when is recommendable to use this way instead of using a struct, considering performance and good practices.

An exposed-field structure is essentially a group of variables bound together with duct tape. It won't behave as an "object", and may thus be seen as evil who think everything should behave like an object; nonetheless, in cases where one doesn't really want an object, but rather a group of variables bound together with duct tape, an exposed-field structure may be a perfect fit.
Anonymous classes have only a few advantages over exposed-field structures:
The syntax to declare them is at least slightly smaller; depending upon coding standards, it may be a lot smaller. If coding standards will allow one to write internal struct WeightAndVolume { public double weight, volume;} and say that the struct is "self-explanatory" [it contains two public fields of type double, named weight and volume, each of which will hold whatever was last written to it by outside code], anonymous classes won't save much, but if coding standards would require that every named data type have many pages of associated documentation, including an analysis of required unit-test procedures, anonymous classes could avoid such hassle.
Copying class references is slightly cheaper than copying structures larger than 8 bytes, though unless a reference would be copied many times, the cost of creating the object will outweigh any savings in copying.
Casting an anonymous class to Object is much cheaper than casting a struct. The first time an anonymous class instance gets cast to Object will make up for the extra costs of creating it. Every additional time will represent a savings of that amount.
Passing a structure to a generic method will require the JITter to produce a specialized version of the code for that type; by contrast, the JITter would only have to produce one piece of code to handle all anonymous classes.
In general, structures will work better than anonymous classes. On the other hand, there are a few scenarios (mostly related to the third point above) where classes can end up being much better.

I wouldn't say it is ever recommended to use anonymous classes, in the sense that it's never wrong to not use them. But they typically get used when
it's an one-shot job, for which creating a proper named type would be cumbersome, and
the consumer of the objects is either compiler-generated code (you don't have access to the types backing those anonymous classes, but the compiler does) or uses reflection (in which case you don't need access to the types at compile time)
The most common scenario where this occurs is in LINQ queries.

Related

What are the disadvantages of using records instead of classes?

C# 9 introduces record reference types. A record provides some synthesized methods like copy constructor, clone operation, hash codes calculation and comparison/equality operations. It seems to me convenient to use records instead of classes in general. Are there reasons no to do so?
It seems to me that currently Visual Studio as an editor does not support records as well as classes but this will probably change in the future.
Firstly, be aware that if it's possible for a class to contain circular references (which is true for most mutable classes) then many of the auto generated record members can StackOverflow. So that's a pretty good reason to not use records for everything.
So when should you use a record?
Use a record when an instance of a class is entirely defined by the public data it contains, and has no unique identity of it's own.
This means that the record is basically just an immutable bag of data. I don't really care about that particular instance of the record at all, other than that it provides a convenient way of grouping related bits of data together.
Why?
Consider the members a record generates:
Value Equality
Two instances of a record are considered equal if they have the same data (by default: if all fields are the same).
This is appropriate for classes with no behavior, which are just used as immutable bags of data. However this is rarely the case for classes which are mutable, or have behavior.
For example if a class is mutable, then two instances which happen to contain the same data shouldn't be considered equal, as that would imply that updating one would update the other, which is obviously false. Instead you should use reference equality for such objects.
Meanwhile if a class is an abstraction providing a service you have to think more carefully about what equality means, or if it's even relevant to your class. For example imagine a Crawler class which can crawl websites and return a list of pages. What would equality mean for such a class? You'd rarely have two instances of a Crawler, and if you did, why would you compare them?
with blocks
with blocks provides a convenient way to copy an object and update specific fields. However this is always safe if the object has no identity, as copying it doesn't lose any information. Copying a mutable class loses the identity of the original object, as updating the copy won't update the original. As such you have to consider whether this really makes sense for your class.
ToString
The generated ToString prints out the values of all public properties. If your class is entirely defined by the properties it contains, then this makes a lot of sense. However if your class is not, then that's not necessarily the information you are interested in. A Crawler for example may have no public fields at all, but the private fields are likely to be highly relevant to its behavior. You'll probably want to define ToString yourself for such classes.
All properties of a record are per default public
All properties of a record are per default immutable
By default, I mean when using the simple record definition syntax.
Also, records can only derive from records and you cannot derive a regular class from a record.

Why are Swift classes and structures set up the way they are?

In Swift, classes have inheritance and structures don't. At the same time, class instances live in the heap while structure instances live on the stack.
This means that only two of four possibilities are allowed: You can have things that support inheritance and which live in the heap, or you can have things that do not support inheritance and which live on the stack. You cannot have things that support inheritance and which live on the stack, and you cannot have things which do not support inheritance and which live on the heap.
Why is this? What makes these latter two possibilities undesirable?
For an encore, why do structures get a free initializer, but classes don't?
This is a reasonable design regarding value-type vs. reference-type.
Class as a reference-type, its inheritance is corresponding to identity. while Struct as a value-type have no identity except for the value on top of the fields they contain, and thus can be freely copied. If you try to add sub-fields to a "inheriting struct", you change the fields, or values, of that struct, and there're no "is-a" relation between them anymore like Class inheritance, since it makes no sense to say that a value-type with fewer fields "is-a" another value-type.
The sub-fields added by the "inheriting struct" could be arbitrarily lost when copying (For example, C++ invoked copy constructors when it happened) and make characteristics like compatibility lose their significance. Class on the other hand don't have these problems, since each instance of a Class has a unique identity, and only references to that instance are passed around.
Let's take a point on a 2D-plane, which is a Struct containing two fields: x and y, for example. Said there's another sub-struct which represented a point on a 3D-world, which had a sub-field z.
When we do like:
point2D = point3D;
What should happen on the assignment line then? since the memory occupied by the point2D is already fixed?
As of your question, it's directly related to the characteristics of heap and stack themselves, when a program entered a function, or a local variable is allocated, they are pushed onto the current stack frame, which is of fixed size, and are poped/deallocated later as the function is exited, this makes it relatively easier to be optimized for the CPU.
The heap, on the other hand, had additional complexity since programmers are able to directly interact with it with commands like malloc or free - resulting in additional request and release times - which had more cost of time; they may require additional memory upon initialization - for the fields that may or may not contain value at the beginning - which had more cost of spaces, etc. Messing these characteristics up would just make optimization more complicated.

Theoretical difference between classes and types

This question has been asked on here a few times, but none of the replies really answered it in the more abstract, theoretical sense that I am looking for.
Most answers are something along the lines of "A class has implementations for methods that its objects can respond to, while a type just specifies which methods can be responded to".
Well, this seems kind of like an odd definition to me. Take ints, floats, and chars in a language like C. It may never be explicitly located in the code, but there are definitely methods built in to the language for responding to the messages ("plus", "minus", etc.) that these types receive.
And as all interfaces must have methods defined somewhere, it seems to me that types are the same thing as classes, except the word "class" carries a mental image of a more substantial programming structure than a "type".
Which leads to me to believe that the drawbacks that apply to any class-based language (the "expression problem" for example) would similarly apply to any language with types (Haskell, etc.)
There is no widely applicable, generally accepted definition of the term "class" that I'm aware of, not even wrt type systems. So your question pretty much depends on the context.
If you are talking about classes in object-oriented languages then the description you quote is relatively accurate. Types are specifications, descriptions (of objects or other values). Classes are implementations, definitions (of object factories).
However, in many OO languages, class definitions also introduce distinct type names, and these type names are often the only means to type objects. That's an unfortunate limitation and conflation of concepts, that also leads to the well-known confusion of subtyping and inheritance. At least some languages separate these concepts properly, e.g. Ocaml.
In any case, the reason why the distinction is seemingly at odds with ints and floats in C is simple: those are not objects. Despite what OO ideology tries to preach, not everything is an object, and certainly not in every language.
Simply put, a class will often have methods that manipulate the data contained within an instance. A type will not; it only is meant to hold and return data.
Although it is true that there may be methods specified somewhere for the type, there will only be one way to change the data contained within an instance of a type - storing a new value in it. The methods are generally along the lines of presenting the data in different ways, instead of actually manipulating the data.
This rule can, of course, be broken; C is full of examples, due to how it is structured (or, rather, not structured). Generally speaking, though, you don't want to have a type with a function that does fancy logic internally.
"Class" and "type" mean different things in different languages and environments; I will try to show here a synthesis that helps me think about the issue.
Classes have objects, and types have values. I think it is easier to understand the difference between objects and values, than between classes and types. An object has 2 independent properties: its identity, and its state/behaviour. So, you can have two different objects with the same class and state. This is not true for values: you cannot have 2 different values of a type that have the exact same state (or form, shape) and behaviour: you cannot have 2 "twoes". A value of a type does not have an identity independent of its state and behaviour.
Mixing both concepts together, you might say that a value of a given type does not necessarily have a class, but an object of a given class necessarily has a type, (e.g. object), and its value is given both by its state/beheviour and by its identity.
Haskell has types, and definable ones if I am correct. It is from Haskell that I am taking the "type" concept I am using. Python has classes and types mixed into the same "type" system, with some primitive types and rich definable classes. The concept of object that I am using is that of the type system of Python, minus its primitive types: int, str, etc.
Another key difference between types and classes would be in their definition. Types are tipically defined by a set of predicates or constraints that "give" all at once all of the values of the type. Therefore, you can use a literal value without first having to "create" it: 23438573. The definition of a class involves a procedure to create objects, and all objects of that class must be created before they are used.

Aggregate class extending base class - Violation of LSP?

The Liskov Substitution Principle (LSP) on Wikipedia
Say I have a Alien class with an numFingers attribute*. Occasionally, I need to pull the sum of the numFingers from the database, grouped by other field values. In these cases, I have no need to manipulate each record individually, but I do need access to a lot of their functionality -- be able to get attributes, perform some basic logic on them, etc. This may include data summed from thousands of records, so it makes little sense to instantiate thousands of Alien objects when the database query can do the work of summing for me.
I would like to make an extension class called AlienAggregate, whose attributes are set from the grouped & summed query. This class would allow me to call any of Alien's methods. The only difference between functionality of the two classes, is GetID(). The aggregate class has no ID, since its data has been derived from any number of records. Because of this, calling GetID() on AlienAggregate throws an exception.
Is this a violation of the Liskov Substitution Principle? Is there a better way to handle a call to GetID()? Is there a better way to design the relationship between the Alien and AlienAggregate classes?
*Actual names may have been changed just because I can.
I don't think you're violating LSP since the principle only applies when Alien is a subtype of AlienAggregate (or the other way around). There is no is a relationship here (more of an aggregation of Alien's as you've appropriately named them).
Instead, it sounds like both Alien, and AlienAggregate probably implement a LooksAlien Interface. The Alien class just has an additional method, GetID().
...just beware of the nefarious BeginInvasion method on AlienAggregate.

NSDictionaries vs. custom objects with properties, what's your take?

I'm writing an App that basically uses 5 business entities, A, B C, D and E
A has some properties and holds a list of B's
B has some other properties and a list of C's and a list of D's
C has some other properties and a list of D's and a list of E's
D has only a few properties
E has only a few properties
There is no inheritance between any of them.
There's no real business logic involved, the objects are created, populated, and then accessed read-only, no further manipulations.
My natural coding style would be to go object oriented and write classes for each of those entities, use NSArrays for the lists, and have the mentioned properties synthesized.
It would make the code readable.
But another approach seems obvious too: only use NSDictionaries and NSArrays, and working with keys/values instead of properties. This seems more efficient, and somehow "closer" to iPhone-style programming to me... but obviously leads to less readable code. Another advantage is there's no additional custom encoding/decoding for serialization required (persisting state to disk, using JSON, ...)
So on the paper, it speaks for the latter approach, on the other hand, it still feels somehow awkward NOT to use custom objects...
Is this really just a matter of taste question? Or are there maybe other arguments in favour/against one of the approaches? Is only using Dictionaries better memory/performance-wise? Is it the preferred "Apple Coding Style"? (I'm coming from Java/C#).
I don't see much difference between Java/C# and Cocoa in this area. Your question is equivalently applicable to those platforms as well (the same also applies to key-value stores and relational stores).
In an object oriented environment, you have to make a trade-off between the flexibility of the key-value approach for storing data and the structured and object oriented style. I'd go with the key-value approach only when I need the flexibility (e.g. the structure is dynamic and might change by user or not known at compile time). Otherwise, taking that route might get you completely off the OOP conventions and benefits (By the way, this is the important point. Does the hassle of sticking to object oriented principles worth it for that specific circumstance? I think your question reduces to this one and to answer it, you should analyze your specific situation)
It largely depends on whether your objects are just collections of data (key/value pairs) or implement their own functionality.
If they're data I'd say go with NSDictionary, it's a lot less code and as you point out you won't have to write serialization routines for each class.
Use a hybrid approach. Store the dictionaries the objects are based on, but expose the most-used values as properties that are either filled when the object is initialized from a dictionary, or have the accessors look into the dictionary for values (less efficient).
Also provide a property to get at the dictionary. This way if you need to propagate a new value quickly to a specific area of the code from the dictionary (presumably a new value added by the server) you have that flexibility. Then if callers are making heavy use of a value you can migrate it to be a true property and get the completion and type checking of a property.