Should I use a Struct? [duplicate] - c#

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
When to use struct in C#?
Hi, I am creating an application that has a class in C# that is purely for holding variables, it does nothing else but set and get these variables. I was wondering, for efficiency and good coding practice, if I should convert this class to a struct so that it is being used properly. I've never used structs before but have been looking into them however I am having some trouble getting it working. Any advice would be appreciated!
Thanks,
Stuart

If the collection of values model a value type (that is, something that doesn't have an identity of its own and two instances with the same values are considered the same) use a struct.
Otherwise, use a class.

Using structures in place of classes depends on the scenario on which you are working. Although you can use structures in place of classes but structures lacks the ability to implement access identifiers (such as Private, Public, Protected). If you are using classes just for holding variables, you can use structures as well, but if your class contains some private, protected or public methods or variables/properties, you can not use structures.
Hope this helps!

The decision for struct or class should be based on "do I want reference type semantics or values type semantics?"
When you use a struct as parameter, the complete contents are copied. For a class just the reference is copied. So a "big struct" could have a performance penalty!

In most cases, a class is preferred. Structs are passed by value, have no inheritance, etc. You mention efficiency, is this class likely to be a performance bottleneck ?
If you make a struct though, make sure to make it immutable

I'm not sure that using a struct or not relates to good coding practise, but there are some performance benefits to using structs under certain circumstances. For example, MSDN suggests that a type which is under 16 bytes in size might be more efficiently handled by a struct than a class.
It's important to understand why a struct might be a better choice and how their memory is managed by the runtime. Libraries which must perform quickly with the minimum of overhead would consider using structs (such as a lot of the Math types in the XNA framework). There are also design issues like the fact that your struct always has a default constructor; if you want to make sure that your type can only be constructed with specific values then a struct isn't the best choice.
The long and short of it is, unless you have a very specific reason to be using structs over classes, just stick with classes.
If you want to press ahead with structs, what issues are you having with them?

It really depends on what you're trying to achieve. The fact that you currently have only getters and setters doesn't mean anything. For example, a type might be modelling the application settings read from a file. At some point you might wish to add a IsValid() or Normalize() methods. So in this case, you'd rather go with a class then a struct.
A struct should be used, when the type's identity is decided by the value of the fields. A good example from the .NET framework is Point, which has X and Y.
The second thing is that structs should be cheap to pass to and from functions:
public bool IsInRange(Point point)
{
// ...
}
Remember that point will be copied field by field here, so that should be fairly cheap.

You use structs when:
Logically represents a single value
Has an instance size less than 16
bytes
Will not be changed after creation
Will not be cast to a reference type
Refere to MCTS 70-536

Related

When to use record struct instead of struct, and vice versa?

I have found out recently about the record keyword in C#, and saw that it can be used as record struct in a way to make it, if I understood correctly, a value type instead of a reference type.
However, I'm having a hard time to understand when exactly to use record struct instead of just the struct. From what I saw, the record struct has some base implementations that the struct doesn't (like the == and != operators, an override of the ToString, and some other things), but is it all that is there for difference between the two? If not, what needs to be considered when deciding to use one or another?
From the way I currently see, it might be better to always use the record struct just to take advantage of those implementations that already comes with it.
This answer assumes:
It is known what the record keyword does in c#;
It is known what a struct is how it is different from class;
Then, the decision of using struct instead of record struct comes down to:
You don't need the default implementation that record bakes in.
Maybe your struct is so short-lived that it will be used only to pass around structured data; it will be created, consumed and be disposed in very well-known places and you are in total control of their usage. If you are totally, completely sure that you don't need equality comparison, pattern matching or string representation, than you could avoid a few bits of meta-data in your assembly and a few lines of documentation.
You don't want the default implementation that record bakes in.
This point is kinda weak, considering that you can declare your type as record struct and still provide a custom implementation of any of the automatic behavior. You can even specify attributes to the auto-properties with the concise syntax. So unless you are planning to provide a custom implementation to most of the automatic ones, you would still benefit from using record.
You can't use record struct because you are locked in a .net version that doesn't support c#10.
Well, not much to say in this case.
In summary, record struct is just better in the general case, and honestly it is what struct should have been by default since it's inception.

Should I use a structure instead of a class to hold string only data in C#? [duplicate]

This question already has answers here:
When should I use a struct rather than a class in C#?
(31 answers)
Closed 7 years ago.
C# question.
Say I have a customers class that has a bunch of props for storing string only data such as name postal data and phone numbers.
I don't use this entity for ORM as I'm only adding it to some type of collection for use during app life cycle.
Additionally I don't need to add any entity specific methods to it or persist the data to xml or database, or even to a webservice.
Is it better to make this a struct rather than a class? or no benefit?
Also side question, should I make the collection Customers, a list structure?
Be harsh, please critique.. :)
struct customer
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
struct Customers<List>
{
private customer cust;
public customer Cust
{
get { return cust; }
set { cust = value; }
}
}
I can't see any value in making the customer a struct. The string fields will all be reference types, so you might as well make the whole thing a reference type (ie. class).
I'd be inclined to use one of the built-in collection types rather than create my on type for Customers. Something like:
List<Customer> Customers = new List<Customer>();
I suppose you could look at When to use struct in C#?
Unless you have identified specific reasons for using a struct, use a class.
Update: due to #Dmitry Lobanov: Eric Lippert's post: The Truth About Value Types
Structs vs. Classes
Structs may seem similar to classes,
but there are important differences
that you should be aware of. First of
all, classes are reference types and
structs are value types. By using
structs, you can create objects that
behave like the built-in types and
enjoy their benefits as well.
Heap or Stack?
When you call the New operator on a class, it will be
allocated on the heap. However, when
you instantiate a struct, it can be
created on the stack. This will yield
performance gains. Also, you will not
be dealing with references to an
instance of a struct as you would with
classes. You will be working directly
with the struct instance. Because of
this, when passing a struct to a
method, it's passed by value instead
of as a reference.
Ref.
For what it's worth, I would never use structs because I so very rarely have a need to provide a data only structure that doesn't have some sort of associated behaviour (validators, formatters, etc...).
The one thing that I do like about the basic concept of a "struct" is that it represents a storage system at it's most basic, and therefore should avoid the need to write all those pernickity custom getters and setters and all that sort of stuff... but then again, we now have those lovely auto-properties which effectively achieve the same result from purely a coding perspective, and while the YAGNI nazi in me might say to use the struct because it is meant to be simple, the realist in me knows that I will inevitably want to change the struct to a class anyway, so why not simply implement the class from the beginning and be done with the matter! ;-)
As for the argument of performance, and other benefits... ask yourself the question "does this really matter". If you're writing a serious real-time system... perhaps you want to be using another tool. If you're simply passing around some data, you've likely got oodles of processing croutons at your disposal, and your killer algorithm might not really need to worry about the nano-second difference it's going to make.
Personally I use structs everywhere I need to store information, as long as it will not cause obvious performance issues. In most projects this is never, since the data is either directly mappable to an existing type or is larger than a reference (affecting the invariable LINQ queries and other manipulation). I find that structs are only viable when I can stick the data in an array and leave it there (modifying the variables directly in the array), the struct is rarely used, or the amount of data in the struct is less than 64 bits (ignoring struct overhead).
As it was explained to me, structs should be used only to store data and translate it from one form to another (ToString or ToArray converters).
Also, structs are more restrictive than classes with the primary differences:
Structs are value types while classes are reference types. This means the whole struct instance is copied when it is assigned while only the memory address of a class instance is copied. Since most programs are 32bit or 64bit it is usually recommended to limit the size of the struct to prevent performance issues related to copying struct instances as compared to class instanceses. While this can be overcome by putting the structs in an array, this moves the structs to the heap (instead of stack). Also, using generics like List always returns a copy of the instance, since they use methods to access the values. See also the Struct Instances vs. Class Instances section in Objects (C# Programming Guide)
Structs can be instantiated on the stack, while classes are always instantiated on the heap. This is controlled by the compiler and does not affect coding, though it may have a small performance benefit (which is rarely ever detectable).
Within a struct declaration, fields cannot be initialized unless they are declared as const or static.
A struct cannot declare a default constructor (a constructor without parameters) or a destructor.
Unlike classes, structs can be instantiated without using a new operator.
A struct cannot inherit from another struct or class, and it cannot be the base of a class.
All structs inherit directly from System.ValueType, which inherits from System.Object while classes inherit from System.Object.
A struct cannot be null (use the generic Nullable struct).

C# why need struct if class can cover it?

Just wondering why we need struct if class can do all struct can and more? put value types in class has no side effect, I think.
EDIT: cannot see any strong reasons to use struct
A struct is similar to a class, with the following key differences:
A struct is a value type, whereas a
class is a reference type.
A struct does not support inheritance
(other than implicitly deriving from
object).
A struct can have all the members a
class can, except the following:
A parameterless constructor
A finalizer
Virtual members
A struct is used instead of a class when value type semantics are desirable. Good examples of structs are numeric types, where it is more natural for assignment to copy a value rather than a reference. Because a struct is a value type, each instance does not require instantiation of an object on the heap. This can be important when creating many instances of a type.
Custom value types aren't absolutely necessary - Java does without them, for example. However, they can still be useful.
For example, in Noda Time we're using them pretty extensively, as an efficient way of representing things like instants without the overhead of an object being involved.
I wouldn't say that "class can do all struct can and more" - they behave differently, and should be thought of differently.
Why use a struct when a class works? Because sometimes a class doesn't work.
In addition to the performance reasons mentioned by Reed Copsey (short version: fewer objects that the GC needs to track, allowing the GC to do a better job), there is one place where structures must be used: P/Invoke to functions that require by-value structures or structure members.
For example, suppose you wanted to invoke the CreateProcess() function. Further suppose that you wanted to use a STARTUPINFOEX structure for the lpStartupInfo parameter to CreateProcess().
Well, what's STARTUPINFOEX? This:
typedef struct _STARTUPINFOEX {
STARTUPINFO StartupInfo;
PPROC_THREAD_ATTRIBUTE_LIST lpAttributeList;
} STARTUPINFOEX, *LPSTARTUPINFOEX;
Notice that STARTUPINFOEX contains STARTUPINFO as its first member. STARTUPINFO is a structure.
Since classes are reference types, if we declared the corresponding C# type thus:
[StructLayout(LayoutKind.Sequential)]
class STARTUPINFO { /* ... */ }
class STARTUPINFOEX { public STARTUPINFO StartupInfo; /* ... */ }
The corresponding in-memory layout would be wrong, as STARTUPINFOEX.StartupInfo would be a pointer (4 bytes on ILP32 platforms), NOT a structure (as is required, 68 bytes in size on ILP32 platforms).
So, to support invoking arbitrary functions which accept arbitrary structures (which is what P/Invoke is all about), one of two things are necessary:
Fully support value types. This allows C# to declare a value type for STARTUPINFO which will have the correct in-memory layout for marshaling (i.e. struct support, as C# has).
Some alternate syntax within P/Invokeable structures which would inform the runtime marshaler that this member should be laid out as a value type instead of as a pointer.
(2) is a workable solution (and may have been used in J/Direct in Visual J++; I don't remember), but given that proper value types are more flexible, enable a number of performance optimizations not otherwise achievable, and make sensible use within P/Invoke scenarios, it's no surprise that C# supports value types.
In general, use a class.
Only use a struct when you absolutely need value type semantics.
Structs are also often required for performance reasons. Arrays of structs take quite a bit less memory, and get much better cache coherency than an array of object references. This is very important if you're working with something like a rendering system, and need to generate 5 million vertices, for example.
For details, see Rico Mariani's Performance Quiz + Answers.
Structs are useful simply because they are passed by value, which can actually be useful in certain algorithms. This is actually something that classes CAN'T do.
struct ArrayPointer<T>
{
public T[] Array;
public int Offset;
}
You can pass this structure to a method and the method can alter the value of Offset for its own needs. Meanwhile, once you return from the method, it will behave as if Offset never changed.
Struct Vs Class in C#
C# Struct usage tips?
Why do we need struct? (C#)
For the average application developer, using classes is the norm. On the surface, classes make structs seem unnecessary, but when you dig deeper into the nitty-gritty details they are actually quite different.
See here for some differences between structs and classes.
The most well-known difference is that classes are reference-types and structs are value-types. This is important because it allows a library developer to control how instances of a data-type can be used.
1, performance. In some cases using structures we'll get much better performance.
2, data immutability. By changing some property of a struct you'll get a new struct. This is very useful in some cases
3, better control of in memory representation. We can exactly define how the struct is located in memory and this allows us to serialize and deserialize some binary data fast and efficiently.
It is almost a must to use for interop with underlying data structure used by win32 API. I suppose a very big reason to have it in .net could be due to that reason.

C# Struct usage tips?

I like using structs a lot.
So after reading this article, are there any other concerns I should have against using them all the time?
See Also:
When should I use a struct instead of a class?
When to use struct in C#?
You should make the following considerations about structs:
structs should be immutable (mutable structs are not intuitive and unpredictable)
structs always have a default (public parameterless) constructor that cannot be changed
struct size should not exceed 16 bytes
the Equals and GetHashCode methods should be overriden for better performance
implementing the IEquatable<T> interface is recommended
redefining and == and the != operators is also recommended
I almost never define custom structs. There just aren't that many natural value types around, IMO.
In particular, I would think very, very carefully before defining a mutable struct, especially if it mutates via an interface implementation. Mutable structs behave in ways which people don't expect at all, leading to code which is hard to understand.
I think it's worth reading "Choosing Between Classes and Structures" from "Design Guidelines For Developing Class Libraries".
In particular:
Do not define a structure unless the
type has all of the following
characteristics:
It logically represents a single
value, similar to primitive types
(integer, double, and so on).
It has an instance size smaller than
16 bytes.
It is immutable.
It will not have to be boxed frequently.
Do you really develop types with all of those characteristics frequently?
They don't fit into an Object Oriented programming paradigm like classes do. They are good for small data structures, but I use classes for anything beyond that.
I think main purpose of a struct - to keep only variable types. If you keep some classes into struct - you're wrong.
Ask yourself the following questions about the set of data you're modeling with a struct:
Might it ever need to have any
get/set logic?
Might it ever need to store ANY logic
that is endemic to the data?
Might it need to inherit another set
of data?
Might another set of data need to
inherit this one?
I think if you can heartily answer "no" to all these questions, then there's no good reason not to use a struct. I think people use static subclasses in certain situations where a struct would be more than good enough.
A class is a lot simpler to implement correctly than a struct. If you implement a struct incorrectly it can give you some unexpected errors.
A struct should not be larger than 16 bytes, or you lose most of the performance benefits.
A struct is intended to be a value type, representing a single entity of some kind.
A struct should be immutable. That means that you never change one of the properties in a struct. If you want a struct value that is different you create a new value.
Use of structs should be limited to when all you really need is a small data structure. (as you read). I would only really use them for the smallest of datastructures like coordinates, offsets, and sometimes for graphics.
In many ways, you can think of structs in C# as being like scaled - down classes. They are basically the same as classes but designed more for cases where you simply want to group some data together. They
differ from classes in the following ways:
Some things to keep in mind
Structs are value types, not
reference types. This means they are
stored either in the stack or in-
line (if they are part of another
object that is stored on the heap)
and have the same lifetime
re-strictions as the simple data
types.
Structs do not support inheritance.
There are some differences in the
way constructors work for structs.
In particular, the compiler always
supplies a default no - parameter
constructor, which you are not
permitted to replace.

Immutability of structs [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why are mutable structs evil?
I read it in lots of places including here that it's better to make structs as immutable.
What's the reason behind this? I see lots of Microsoft-created structs that are mutable, like the ones in xna. Probably there are many more in the BCL.
What are the pros and cons of not following this guideline?
Structs should represent values. Values do not change. The number 12 is eternal.
However, consider:
Foo foo = new Foo(); // a mutable struct
foo.Bar = 27;
Foo foo2 = foo;
foo2.Bar = 55;
Now foo.Bar and foo2.Bar is different, which is often unexpected. Especially in the scenarios like properties (fortunately the compiler detect this). But also collections etc; how do you ever mutate them sensibly?
Data loss is far too easy with mutable structs.
The big con is that things don't behave how you expect them to - particularly if the mutability comes from a mixture of the direct value and a reference type within it.
To be honest, I can't remember off the top of my head all the weird problems I've seen people come up with in newsgroups when they've used mutable structs - but those reasons certainly exist. Mutable structs cause problems. Stay away.
EDIT: I've just found an email I wrote a while ago on this topic. It elaborates just a little bit:
It's philosophically wrong: a struct should represent some sort of fundamental value. Those are basically immutable. You don't get to change the number 5. You can change a variable's value from 5 to 6, but you don't logically make a change to the value itself.
It's practically a problem: it creates lots of weird situations. It's particularly bad if it's mutable via an interface. Then you can start changing boxed values. Ick. I've seen a lot of newsgroup posts which are due to people trying to use mutable structs and running into issues. I saw a very strange LINQ example which was failing because List<T>.Enumerator is a struct, for example.
I use mutable structs often in my (performance critical) project - and I don't run into problems, because I understand the implications of copy semantics. As far as I can tell, the main reason people advocate immutable structs is so that people who don't understand the implications can't get themselves in trouble.
That's not such a terrible thing - but we're in danger now of it becoming "the gospel truth", when in fact there are times where it is legitimately the best option to make a struct mutable. Like with all things, there are exceptions to the rule.
There is nothing cheaper to manipulate than a mutable struct, which is why you often see it in high performance code like the graphics processing routines.
Unfortunately mutable structs don't play well with objects and properties, it is way too easy to modify a copy of a stuct instead of the struct itself. Thus they aren't appropriate for most of your code.
P.S. To avoid the cost of copying mutable structs, they are usually stored and passed in arrays.
The technical reason is that mutable structs appear to be able to do things that they don't actually do. Since the design-time semantics are the same as reference types, this becomes confusing for developers. This code:
public void DoSomething(MySomething something)
{
something.Property = 10;
}
Behaves quite differently depending on if MySomething is a struct or a class. To me, this is a compelling, but not the most compelling reason. If you look at DDD's Value Object, you can see the connection to how structs should be treated. A value object in DDD can be best represented as a value type in .Net (and therefore a struct). Because it has no identity, it can't change.
Think of this in terms of something like your address. You can "change" your address, but the address itself hasn't changed. In fact, you have a new address assigned to you. Conceptually, this works, because if you actually changed your address, your roommates would have to move too.
You have asked for the pros and cons of not following the guideline that structs should be immutable.
Cons: The cons are well covered in existing answers, and most problems described are due to the same cause - unexpected behaviour due to structs' value semantics.
Pros: The main pro of using mutable structs can be performance. Obviously, this advice comes with all the usual caveats about optimisations: make sure that part of your code needs to be optimised and make sure any changes do actually optimise your code's performance via profiling.
For an excellent article discussing when you might want to use mutable structs, see Rico Mariani's Performance Quiz on Value-Based Programming (or more specifically, the answers).
A struct should generally represent a single unity of some kind. As such it doesn't make much sense to change one of the properties of the value, it makes more sense to create a completely new value if you want a value that is different somehow.
The semantics gets simpler when using immutable structs, and you avoid pitfalls like this:
// a struct
struct Interval {
int From { get; set; }
int To { get; set; }
}
// create a list of structs
List<Interval> intervals = new List<Interval>();
// add a struct to the list
intervals.Add(new Interval());
// try to set the values of the struct
intervals[0].From = 10;
intervals[0].To = 20;
The result is that the struct in the list is not changed at all. The expression Interval[0] copies the value of the struct from the list, then you change the property of the temporary value, but the value is never put back in the list.
Edit: Changed the example to use a list instead of an array.
When you copy structs around you copy their contents, so if you modify a copied version the "original" will not be updated.
This is a source for errors, since even if you know that you fall into the trap of copying a struct (just by passing it to a method) and modifying the copy.
Just happened to me again last week, kept me an hour searching for a bug.
Keeping structs immutable prevents that ...
Other than that you need to make sure you have a really good reason to use structs in the first place - "optimization" or "I want something that allocates quickly on the stack" does not count as an answer. Marshaling or things where you depend on layout - ok, but you should not typically keep those structs around for very long, they are values not objects.
the reason you should make structs immutable is that they're ValueTypes, meaning that they are copied every time you pass them to a method.
So if, for example, you had a property that returned a struct, modifying the value of a field on that struct would be worthless, because the getter would return a copy of the struct, rather than a reference to the struct. I've seen this done in code, and it's often difficult to catch.
If you design your structs for immutability, you help the programmer avoid these mistakes.

Categories