C# Struct usage tips? - c#

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.

Related

Are nested structs in C# good or bad

I have gotten into the habit of declaring structs nested inside the class that I use them in because that is how I learnt to use them when I first learnt about structs.
If a struct is almost like a class in C# then shouldn't I be declaring structs in a separate file and not nested inside another class?
If the struct is purely an implementation detail of that one class, then it makes perfect sense to declare structs inside a class. I declare structs (and classes!) inside other classes for this reason.
Nested structs, as well as nested classes are good when the nested struct/class is only relevant to use with the outer struct/class, like if it is the type of a member property of the struct/class or only used internally.
Just note that to much nested structs is a warning sign and that you should consider making it classes instead. As MSDN(struct) notes.
Unless you need reference type semantics, a class that is smaller than 16 bytes may be more efficiently handled by the system as a struct.
And the other way around, if your struct with nested structs grow way beyond 16 bytes you should consider using classes instead unless you need the pass by value semantics.
It depends.
If they all share a common theme, maybe putting them in an apropriately named file would be a good idea. Otherwise if they're just a detail of a class I'd put them at the end of the class, right before subclasses (if any).

Should I use a Struct? [duplicate]

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

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#: Are struct members more performant?

On a blog entry, Luca Bolognese ponders this idea about structs vs. classes as member fields:
The reason to use a struct is to not
allocate an additional object on the
stack. This allows this solution to be
as 'performant' as simply having coded
the fields on the class itself. Or at
least I think so ...
How accurate is this?
First, doesn't he mean allocate an additional object on the heap?
And, wouldn't using structs marginally decrease allocation time (especially if the class members were lazy-loaded) at the expense of increasing the memory footprint?
Would you recommend this practice of structs over classes in certain situations?
I think he did mean to write heap, he just wrote stack by mistake.
The question of structs or classes comes up quite often. Here's one example. I think it's best to follow this commonly given advice:
MSDN has the answer: Choosing Between Classes and Structures.
Basically, that page gives you a 4-item checklist and says to use a class unless your type meets all of the criteria.
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.
Are there times you shouldn't follow this advice? Maybe, but only after you've proved it by profiling.

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