c# Storing a generic reference to have self updating snapshots - c#

I have a class called "RelativeData" that is used for comparing values through a state machine. I am trying to build a class that takes snapshots of the data at given intervals. The intervals being: StateBegins, StateMachineBegins, and the one I'm having issue with, liveValue.
The challenge im having is the liveValue(s) I wish to track are in a separate class, There is a large list of values I want to add to track with my RelativeData objects, so my class needs to be generic.
the point of this class is to take snapshots of data.
class RelativeData<T>
{
T initialValue;
T stateValue;
T liveValue; //currently not implemented, since i can't store a ref
public void StateMachineActive(T curValue)
{
initialValue = curValue;
}
public void StateUpdated(T curValue)
{
stateValue = curValue;
}
}
ex) a float called "energy" which belongs to a spell. When the state machine activates, it calls StateMachineActive on my list of relativeData, which preferably could internally update using liveValue, instead of having to pass curValue
Current fix)
I have a manager that adds these values to dictionaries of the generic types.
Dictionary<myKey,relativeData<bool>> relativeBoolData
Dictionary<myKey,relativeData<float>> relativeFloatData
& etc...
However to call StateUpdated, i need to pass the current value, which i need to get from a large switch case using myKey. Doable, but back in C++ days I could just store a T*. Can't turn on unsafe mode since Unity doesn't seem to allow it. I could have the actual values just stored in there, but then everytime I want to get the currentValue (which happens ALOT more often than getting a relative value) everywhere throughout the code, it would increase complexity(be more proc heavy). At least I assume.
Question:
1) Can I store a pointer to a Icomparable type? Can I have liveValue point to a valueType/Primitive data type (ie int, long, enum) elsewhere, like I could in C++ with T*. I know I can pass using "ref" but I can't seem to store it.
2) Should I just store the actual values in there instead, and have everything be retreived through a two tier switch case (First to know which dict to call, the float, bool... and then to retrive the value) would that not increase runtime too heavily? The non-relative values: energy, stability, etc, are used continuously in spells for internal calculations. The relative only used for state machine. (may have 2~60 spells active at once)
3) Is this just a bad pattern, is there a better pattern that I am just not seeing, a better way to take snapshots of generic data?
4) I know arrays are by ref, but that would mean my original data would all have to become arrays right?
5) Should I just leave it the way it is. It works, just a tad messier and slower.
all of them are IComparable: ints, floats, bools, enums..

You can do one of the following:
Create a wrapper class for the values and keep a reference on the wrapper.
public class Wrapper<T>
{
public T Value { get; set; }
}
Store the values in an array and remember the indexes instead of the values themselves.
Store the values in a dictionary and remember their keys instead of the values themselves.
Store an accessor delegate (Func<T>). Note: Lambda expressions automatically keep a reference on the context in which they were first declared. See The Beauty of Closures (by Jon Skeet).

Related

Where should I store different types of value?

After Python and JavaScript I started using C# and can't understand some basic concepts.
In Python and JavaScript I used to store everything in a heap without thinking about the type of object. But in C# I can't create Dictionary or List with different type of object.
I want to store some mouse and keyboard events. For that, I use instances of class, like this:
class UserActionEvent
{
public MacroEventType Type;
public int[] MouseCoordinate = new int[2];
public string MouseKey;
public string KeyBoardKey;
public int TimeSinceLastEvent;
}
And all instances is saved in Queue. But I worry whether it is normal to store several thousand objects like this? Maybe there is a more universal way to store data of different types?
Storage in C# is not much different from Python in JavaScript in that it uses a garbage collected heap (of course every runtime has its own way of implementing the GC). So for "normal" classes you can just go ahead and treat them as you would in JS.
C#, however, also has the concept of value types, which are typically allocated on the stack. The stack has a much more limited space than the heap, so this is where you need to be a bit more careful, but it is unlikely that you accidentally allocate a large amount of stack space, since collection types are all reference types (with the exception of the more exotic stackalloc arrays that you should stay away from unless you are sure what you are doing). When passing value types between methods, they are copied, but it is also possible to pass them by reference (for example by casting to object). This will wrap the value type in a reference type, a process called boxing (the opposite process is called unboxing).
To create a value type, use struct instead of class. In your example above, using a value type for the mouse coordinate, e.g.
struct Point {
public int X, Y;
}
instead of an int array would likely save memory (and GC CPU time) since in your example you would have to allocate a reference object (the array) to hold only eight bytes (the two ints). But this only matters in more exotic cases, maybe in the render loop of a game engine, or if you have huge data sets. For most type of programs this is likely to be premature optimization (though one could argue creating the struct would make the code more readable, which would likely then be the main benefit).
Some useful reads:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/value-types
https://medium.com/fhinkel/confused-about-stack-and-heap-2cf3e6adb771
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/stackalloc
If you want to store different type of objects on c# I recommend the use of ArrayList
With ArrayList you can store any type of object since it is a dynamic collection of objects.
ArrayList myAL = new ArrayList();
myAL.Add("Hello");
myAL.Add("World");
myAL.Add("!");
You will need a
using System.Collections;
To be abel to use this collection

Make answer class a struct?

Usually play around with making games but I'm taking a detour into making a little question and answer app, for educational purposes.
Anyway I have a question class which holds numerous members: the question itself, the answer to the question, an array of possible answers etc. No doubts this should be a class.
My answer class however only holds a string, an Enum and an int id number as shown below:
public class Answer
{
public string Answer { get { return answer;} private set { answer = value; } }
public Answer_Category = Some_Value; // The enum.
public int ID { get { return id; } private set { return id; } }
private string answer;
private int id;
}
Ok so it holds two strings, also the ctor has been out.
So should I be making this a struct? I ask as it seems comparable to making a Vector a struct, being such a small data structure 'n all.
Naturally being a question and answer application the answer class/struct is going to be the subject of a lot of search calls.
IMO this should be a struct - solely because of the size of the structure, haven't played around with C# for some time though so just looking for some clarification.
The decision boils down to whether you want a value type or a reference type. In other words what do you want the assignment operator to mean? If you want assignment to copy the value, use a struct. If you want assignment to take another reference e, use a class.
There are two primary usages cases for structures: for situations where one wishes to conveniently move around aggregations of independent variables (such as the coordinates of a point), or where a small immutable object will often be used in situations where identity is not important (as would be the case with e.g. Decimal or DateTime). Since a variable of structure type simply holds an aggregation of variables, structures which are used for that purpose should simply expose their contents as public fields. Doing so will make clear that any invariants that might be applicable to structure members will be the responsibility of the code creating the structure. For example, if one has a structure MinMax with int members Minimum and Maximum, using exposed public fields for those members would make clear that the structure itself makes no promise that Maximum >= Minimum. A method which returns such a structure may promise that it will not return one where Maximum < Minimum, but methods which receive structures and want Maximum >= Minimum will have to check those fields themselves. On the flip side, code which wishes to set those values in a structure will be able to set them in whatever order is convenient, without having to worry about the struct throwing an exception because the Minimum was set higher than Maximum.
The MSDN guidelines assume that the purpose of any struct is to behave like an object. Since piecewise-mutable structures don't behave like objects, structures which will be used like objects shouldn't be piecewise mutable. On the other hand, aggregations of variables can be useful in and of themselves; one should use a struct in cases where one wants an aggregation of variables, but should try to make it as obvious as possible that the struct is an aggregation of variables rather than an object.

Strategies for passing colors around (avoiding ref?)

I'm refactoring code in an aging windows application, and I've come across a pattern of sorts, that I'm not sure I like: A class has got global color variables, like the following:
private Color myForegroundColor = Color.Azure;
private Color myBackgroundColor = Color.Empty;
// ...etc.
There are a bunch of these, and they are being passed around by ref to methods responsible for setting up certain parts of the UI.
I gather that a Color is a struct, and that each color is therefore passed by ref in order to avoid creating new copies of it each time a method is called. IE something like:
// Avoid creating a copy of myForgroundColor inside SetUpButton():
MyHelperClass.SetUpButton(ref myForegroundColor);
I can't help feeling that this usage of ref throughout this class and related classes is bad. It feels like a "code smell", though I can't really put my finger on why.
I've seen a couple of posts on similar issues, with recommendations like "use a class containing colors, which is then passed as a value type", but it is not entirely clear how it would be best to do this.
What I would like to do is create something similar to the following:
public class ColorContainer
{
public UiSettingsContainer()
{
MyColor = Color.Black;
MyNextColor = Color.Blue;
// ..etc...
}
public Color MyColor { get; private set; }
// ...etc....
}
This would let me retain control of the colors, but the implications on memory are a little unclear to me; if I created an instance of this class and passed that around to the methods needing info about the contained colors, would not a copy of a color (with it being a struct) be created as soon as an implementing method makes use of it?
Am I correct in assuming that this code would create a new copy, and thus be less effective...
// Assumption: This creates a new copy of color in memory.
public void SetSomeColor(Color col){
someComponent.color = col;
}
// Calling it:
SetSomeColor(myColorContainerInstance.MyColor);
... than this code, which would only make use of the existing struct?:
// Question: Does this avoid creating a new copy of MyColor in memory?
public void SetSomeColor(ColorContainer container){
someComponent.color = container.MyColor;
}
// Calling it:
SetSomeColor(myColorContainerInstance);
I'm currently leaning toward a solution similar to the following, in which i gather the colors in a separate class and reorganize the code a bit, but keep using ref. In this case, however, MyColor will have to be a public field in ColorContainer, which means I will have less control over who can set it's value:
// Assumption: This creates a new copy of color in memory.
public void SetSomeColor(ref Color col){
someComponent.color = col;
}
// Calling it:
SetSomeColor(ref myColorContainerInstance.MyColor);
Is this a good solution, or are there better strategies to handle resources like this?
This whole thing smells like premature optimization, parts 3 and 4 of the link specifically, so...
Another solution would be to just remove the refs, and copy the Color struct whenever is needed. The struct itself is not too big (4 byte members and 4 bool members), and unless you are calling the code that changes color several million times per second, the time and memory required is not an issue.
The "slots" analogy has long been one of my favorites for this type of thing. Each method parameter (consider the right hand of assignments as parameters as well) is a slot. Each slot must be filled with something of the correct size and "shape" (type) in order for a method to be called (or an assignment to be processed).
In the case that your method requires a ref Color you're filling the slot with whatever size pointer to a Color struct in memory. Of course I don't mean the C style pointer but it's still the same sort of thing - it's a number that indicates the location of the resource you intend to use even if it's not represented in code as such. In the case of Color (without ref) you're filling it with the Color struct itself.
Depending on the platform you've compiled for, that value that you're passing around (for by ref passing of Color) will either be 32 or 64 bits in length. The color struct (System.Windows.Media.Color) itself being only 32 bits in length (or 64 bits in length if you're using System.Drawing.Color) makes this an unattractive proposition - making the average case scenario the exact same (in terms of the number of copies of the pointers and sizes of the things loaded onto the stack) as passing the struct by value - better only in the 64 bit struct/32 bit platform pairing and worse only in the 32 bit struct/64 bit platform pairing. The actual value of the struct will still be copied into its target slot even after this attempt to just have it use the same instance.
Now, bundling colors together in a class (where by ref passing is default) changes this picture a bit. If your class contains say 3 colors, you've got 96 bits (or 192 bits) of color data contained in it, passing around a maximum of 64 bits of information to find the location of the correct "package" for that information in memory. The colors will still be copied into their target slots even after the packaging; but now we've added overhead from having to either ldfld (load field)/call (call a pre-resolved method - property access) + ldfld/callvirt (call a runtime resolved method - property access) + ldfld to actually get the value. From a performance viewpoint this doesn't really help you at all, unless you intend to pass tons of data and then not use it.
The long story short - unless there's some logical grouping of color information you're trying to achieve, don't bother. Value types on the stack are cleaned up immediately when the stack frame is popped so unless your program is running at ~8 bytes short of your system's total memory you're really gaining nothing with the by ref approach. The wrapper class for a collection of colors would likely make the code cleaner/better factored but not more performant.
Passing structs by ref is generally a good thing unless either (1) one wants pass-by value semantics, or (2) the struct is small and one can live with pass-by-value semantics.
If one will frequently be wanting to around some variables (which might be structs themselves) as a group, it may be helpful to declare a transparent struct type to hold them, and then pass that by ref.
Note that passing a struct by ref has essentially the same cost as passing a class reference by value. Writing a class to hold the struct, purely so that one can avoid using ref parameters, is not apt to be a performance win. In some cases it may be useful to have a type
class MutableHolder<T>
{ public T Value; }
which could then apply reference semantics to any struct type, but I would only suggest doing that if one needs to persist a reference outside the current scope. In cases where ref will suffice, one should use ref.

Adding a reference to a list c# struct

I'm having a problem with BoundingSpheres in XNA. I'm wanting to add a BoundingSphere to a list of BoundingSpheres. At the moment it's along the lines of:
Aircraft(Vector3 pos, float radius, CollisionManager colMan)
{
BoundingSphere sphere = new BoundingSphere(pos, radius);
colMan.AddSphere(sphere)
}
List<BoundingSphere> spheres = new List<BoundingSphere>();
CollisionManager()
{
spheres = new List<BoundingSphere>();
}
AddSphere(BoundingSphere boundingSphere)
{
spheres.Add(boundingSphere);
}
Rather then a reference being added, it seems to be adding the values. I believe this is because boundingSpheres are structs? How can I get round this? I tried the ref keyword, but the values still aren't being updated in the list.
To be straightforawrd, you can't, at least not directly. Structs are value types, and are thus passed and stored by value. Even judicious use of the ref keyword won't get around it because List<T>.Item can't return a reference to a value type.
The work-arounds are to either turn your struct into a class, or embed the stuct inside a class, or, just deal with the fact it's a value type and treat it appropriately (ie, don't try to modify local copies, but replace values in the list when the change). The last option is, imo, the best.
Value types are passed by value (this means that you're getting fresh new copy in the method or in the container) to avoid this you can change your struct to class, add an interface to struct declaration and box your struct to store reference to the interface instead.
But it seems that you're using mutable struct and this is a very dangerous because you can face really dangerous behavior (see mutable structs considered harmful for more details).
You'd have to change the definition of BoundingSphere from a class to a struct. This is impossible since it's defined in an assembly outside of your control.
You can't box the structure, as every time you unbox it, you're going to get a copy of the structure you're holding.
That said, the only way you can do this (and this isn't a good idea, in my opinion) is by creating a class wrapper for the structure, and delegating all of the calls from the properties to the structure internally:
public class BoundingSphereWrapper
{
// Set through constructor.
private readonly BoundingSphere _boundingSphere = ...;
// One of the forwarded calls.
public ContainmentType Contains(BoundingBox box)
{
// Forward the call.
return _boundingSphere.Contains(box);
}
// And so on...
}
Of course, you can't pass these class instances to members that expect a BoundingSphere, and you'd have to try and detect changes (which are near impossible, unless the instances are passed by reference) when you expose the underlying structure.
Namely, though, you don't really want to do this; the designers of the structure probably chose it as a structure for the following reasons:
While mutable (which is a no-no when dealing with structures), the lifetime is intended to be limited
There could be many of these instantiated at the same time, and it's more efficient to do this on the stack than to do it on the heap (that would cause lots of first generation garbage collections, which can definitely have an impact on performance on a gaming platform)

Structs - real life examples? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
There are any number of questions here on SO dealing with the differences between Structs and Classes in C#, and when to use one or the other. (The one sentence answer: use structs if you need value semantics.) There are plenty of guidelines out there about how to choose one or the other, most of which boil down to: use a class unless you meet these specific requirements, then use a struct.
This all makes sense to me.
However, I can't seem to find any real-life examples of people using structs in a system. I'm (semi-)new to C#, and I'm having trouble imagining a concrete situation where structs are really the right choice (at least, I haven't run into one yet.)
So, I turn to the SO world-brain. What are some cases where you actually used a struct in a system where a class wouldn't have worked?
Well a class would still work for it, but an example I could think of is something like a Point. Assuming it is an x and y value, you could use a struct.
struct Point {
int x;
int y;
}
In my mind, I would rather have a more simple representation of a pair of integers than to define a use a class with instantiations when the actual entity does not really have much(or any) behavior.
I used a struct to represent a Geolocation
struct LatLng
{
public decimal Lattitude
{
get;
set;
}
public decimal Longitude
{
get;
set;
}
}
this represents a single entity, for instance I can add 2 LatLng's together or perform other operations on this single entity.
MSDN-struct
The struct type is suitable for
representing lightweight objects such
as Point, Rectangle, and Color.
Although it is possible to represent a
point as a class, a struct is more
efficient in some scenarios. For
example, if you declare an array of
1000 Point objects, you will allocate
additional memory for referencing each
object. In this case, the struct is
less expensive.
Also if you look at primitive types Int32,decimal,double..etc you will notice they are all structs, which allows them to be value types whilst allowing them to implement certain crucial interfaces.
Structs are also typically used in graphics/rendering systems. There are many benefits to making points/vectors structs.
Rico Mariani posted an excellent quiz on value based programming. He discussed many reasons to prefer structs in specific situations, and explained it in detail in his quiz results post.
A Money struct is probably one of the most common, however Phone number or Address are also common.
public struct Money
{
public string Currency { get; set; }
public double Amount { get; set; }
}
public struct PhoneNumber
{
public int Extension { get; set; }
public int RegionCode { get; set; }
//... etc.
}
public struct FullName
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
}
Keep in mind though that in .NET your structs should not be larger in memory footprint than 16 Bytes, because if they get bigger the CLR has to allocate additional memory.
Also because structs 'live' on the stack (and not the heap as reference types do) you might consider using structs if you need to instantiate a lot of the same types of objects.
The quintessential example is the frameworks nullable types, such as int?. These use structs so they retain the value semantics of an int, yet providing a way to make them null without boxing and turning them into reference types.
You would use a struct when you don't want to pass something by reference. Suppose you have a collection of data, or an object that you wish to pass by value (ie, anything you pass it to is working with its own unique copy, not a reference to the original version) then a struct is the right type to use.
They provide a default implementation for Object.GetHashCode(), so you might want to use a struct instead of a class when the object is a simple collection of non-reference types that you want to use as keys to a dictionary.
They are also useful for PInvoke/interop or low-level networking scenarios where you want precise control over the binary layout of a data structure. (go to www.pinvoke.net for lots of interop code that requires structs)
But really, I never use them myself. Don't sweat not using them.
Basically I try to NOT use them. I find they confuse other developers on the team and thus are not worth the effort. I have only found one case to use it, a custom Enum-like type we use a code generator to produce from XML.
The key for me is to define if I want to keep reference to the same object.
Which makes sence when struct is part of another entity, but does entity itself.
In the example above with LatLong that makes perfect sence, for example. You need to copy values from one object to another, not keep referensing the same object.
I often use structs to represent a domain model value type that might be represented as an enum, but needs an arbitrary unlimited number of discrete values, or I want it to have additional behavior (methods) that you cannot add to an enum... For example, in a recent project many data elements were associated with a specific calendar Month rather than with a date. So I created a CalendarMonth struct that had methods:
static CalendarMonth Parse(DateTime inValue);
static CalendarMonth Parse(string inValue);
and TryParse( ) method,
static bool TryParse(string inValue, out CalendarMonth outVal);
And Properties
int Month { get; set; }
int Year { get; set; }
DateTime StartMonthLocal { get; set; }
DateTime StartMonthUTC{ get; set; }
DateTime EndMonthLocal { get; set; }
DateTime EndMonthUTC { get; set; }
etc.
im not usually concerned with 'data-density' in my business apps. I will typically always use a class unless I specifically want value semantics
this means that i am forseeing a situation where i want to compare two of these things and i want them to show up as the same if they have the same value. With classes this is actually more work because i need to override ==, !=, Equals, and GetHashcode, which even if resharper does it for me, is extra needless code.
So in my mind, always use classes unless you know that you want these things to be compared by value(in this case component value)
So I take it you've never used DateTime (a struct).
I can't believe no one has mentioned XNA: in XNA, almost everything is a struct. So when you do
Matrix rotation = Matrix.CreateRotationZ(Math.PiOver2);
You are really creating a value-type.
This is because, unlike in applications programming, a stall of a few milliseconds while the garbage collector runs is not acceptable (we only get 16.6 ms to render the entire frame!), so we have to avoid allocations as much as possible so the GC doesn't have to run as much.
This is especially true on the XBox 360, where the GC is nowhere near the quality it is on the PC - even an average of one allocation per frame can kill performance!
I have been working in financial institutions where large scale caching and latency requirements was achieved using structs. Basically structs can spare the garbage collector of A LOT of work.
See these examples:
http://00sharp.wordpress.com/2013/07/03/a-case-for-the-struct/
http://00sharp.wordpress.com/2013/07/04/a-case-for-the-structpart-2/
Basically, I use Structs for modeling geometric and mathematical data, or when I want a Value-based data-structure.
The only time I've ever used a struct was when I was building a Fraction struct:
public struct Fraction
{
public int Numerator {get;set;}
public int Denominator {get; set;}
//it then had a bunch of Fraction methods like Reduce, Add, Subtract etc...
}
I felt that it represents a value, just like the built in value types, and therefore coding against it would feel more natural if it behaved like a value type.
I think the .Net Framework is quite real life. See the list under "Structures":
System Namespace
In some performance-critical situations, a struct (a value type and thus allocated from the stack) can be better than a class (a reference type and thus allocated from the heap). Joe Duffy's blog post "A single-word reader/writer spin lock" shows a real-life application of this.
One I've created in the past is StorageCapacity. It represented 0 bytes to N exabytes (could have gone higher to the yottabyte, but exa seemed enough at the time). The struct made sense since I worked for a storage management company. You would think it was fairly simple: a struct with a StorageUnit (enum) and a Quantity (I used decimal). But when you add in conversions, operators, and classes to support formatting, parsing, etc. it adds up.
The abstraction was useful to enable you to take any StorageCapacity and represent it as bytes, kilobytes, etc. without having to multiply or divide by 1024 many times.
I have given my reasons for using structs already elsewhere (When to use struct in C#), and I have used structs for these reasons in real-life projects:
I would choose to use structs for performance reasons if I needed to store a large number of the same item type in an array, which may happen in image processing.
One needs to use structs for passing structured data between C# and C++.
Unless I have a very good reason to use them I try to avoid them.
I know that some people like to use them for implementing value semantics but I find that this behavior is so different from the "normal" assignment behavior of classes (in C#) that one finds oneself running into difficult to trace bugs because one did not remember that the object one was assigning from or to had this behavior because it was implemented as a struct instead of a class. (It has happened to me more than once, so I give this warning since I actually have been burned by the injudicuous use of C# structs.)
I'm not sure how much use this is, but I discovered today that whilst you cannot have instance field intializers in structs, you can in classes.
Hence the following code will give compilation errors, but if you change the "struct" to "class" it compiles.
public struct ServiceType
{
public bool backEnd { get; set; }
public bool frontEnd { get; set; }
public string[] backEndServices = { "Service1", "Service2" };
public string[] frontEndServices = { "Service3", "Service4" };
}
A struct in C# is at its heart nothing more nor less than a bunch of variables stuck together with duct tape. If one wants each variable of a particular type to represent a bunch of independent but related variables (such as the coordinates of a point) stuck together with duct tape, it's often better to use an exposed-field struct than a class, regardless of whether "bunch" means two or twenty. Note that although Microsoft's struct-versus-class advice is fine for data types which encapsulate a single value, it should be considered inapplicable for types whose purpose is to encapsulate independent but related values. The greater the extent to which the variables are independent, the greater the advantages of using an exposed-field struct.
If one wishes to use a class to encapsulate a bunch of independent variables, there are two ways one can do it, neither of which is terribly convenient. One may use an immutable class, in which case any non-null storage location of that class type will encapsulate the values held by the instance identified thereby, and one storage location may be copied to another to make the new one encapsulate those same values. Unfortunately, changing one of the values encapsulated by a storage location will generally require constructing a new instance which is just like the old one except with that value changed. For example, if one has a variable pt of type Immutable3dPoint and one wished to increase pt.X by one, one would have to do something like: pt = new Immutable3dPoint(pt.X+1, pt.Y, pt.Z); Perhaps tolerable if the type only encapsulates three values, but pretty annoying if there very many.
The other class-based approach is to use a mutable class; this generally requires that one ensure that every storage location of the class type holds the only reference anywhere in the universe to an instance of that class. When a storage location is created, one must construct a new instance and store a reference there. If one wishes to copy the values from storage location P to storage location Q, to another, one must copy all the fields or properties from one instance to the other (perhaps by having the type implement a CopyFrom method, and saying Q.CopyFrom(P);. Note that if one instead says Q=P; that may seem to work, but future attempts to modify P will also modify Q and vice versa. Mutable classes may work, and they can at times be efficient, but it's very easy to mess things up.
Exposed-field structures combine the convenient value-copy semantics of immutable classes with the convenient piecewise modifications allowed by mutable classes. Large structures are slower to copy than are references to immutable objects, but the cost of modifying part of an exposed-field structure depends only upon the extent of the modification, rather than upon the overall structure size. By contrast, the cost of changing one piece of data encapsulated in an immutable class type will be proportional to the total class size.

Categories