C# Limitations of struct. Why are they sealed? [duplicate] - c#

This question already has answers here:
Why are .NET value types sealed?
(4 answers)
Closed 9 years ago.
I am having a bit of an issue grasping the concept of the struct and no one can answer my question.
I know it is "like" an object, you can have methods and fields.
What I do not understand is why they are sealed. Why is there a lack of inheritance and polymorphism
which limits their abilities. Is there really much real world use for a struct, I know they are smaller than
an object, I just cannot find any real examples that help me understand the benefits.
Thanks.

Because a struct is a value; a struct that contains a float is exactly 4 bytes long. There is no object-header that indicates what the concrete type is: the thing that knows the type is the compiler (and the resulting IL) - the type information is not self-contained in the value. So, regular polymorphism cannot work. If you do:
MyType type = new MySubType(); // if this was a struct and if this compiled
then from the compiler's perspective, the type of that is MyType. There is no notion, after the assignment, that this is or ever was a MySubType. Indeed, you can use unsafe code to force the bits of one value-type into another.
Additionally, this same facet of structs means that you would not be able to add fields in sub-types: the size has to be fixed, which makes this impossible.
Basically, if you are thinking in terms of inheritance, you are using structs incorrectly; actually, most times that I see people using structs they are using them incorrectly. structs should represent values (ideally immutable etc).
Is there really much real world use for a struct
Yes; for representing values - a ComplexNumber type for example; and for some highly optimized scenarios where GC is prohibitive, but which only affects a small number of developers. Here's one example of this; another common example is "games", but: switching between class and struct is a much bigger change than changing the keyword. You need to know what you are doing, and why you are doing it.
What you should not do is things like:
// ***BAD CODE: DO NOT DO***
public struct Customer
{ // I don't need inheritance; a struct will be faster and smaller
// yay me, I'm awesome
public int Id;
public string Name;
}
The above is clearly best represented as a class. Also: properties.
I know they are smaller than an object
In some ways, this is not true; for example, most useful structs are larger than a reference - which can be problematic if you are passing super-sized structs around on the stack without thinking what you are doing.

It is simple. It is a value type and all value types are sealed. Though you can inherit it from interface.

Related

Should this stll be a struct or better a class(9 value type properties and 1 reference value) [duplicate]

This question already has answers here:
When should I use a struct rather than a class in C#?
(31 answers)
Closed 1 year ago.
Imagine I have have a struct with 9 properties, which return a value type as its result and in that struct I also have a property which returns a reference type : IEnumerable like this:
public IEnumerable<KeyValuePair<String, String>> Dostuff
{
get
{
//doing some operations in here
return _valueToReturn;
}
}
Using IEnumerable will require heap space, but actually the struct is based on the stack, so what to do in my case?
By the way the struct is immutable.
There's a page that shows how to choose between struct and class.
As I understand, if the total size of all fields in the struct is less than 16 bytes, keeping it as struct is better than changing it to class. The number of properties doesn't matter.
In your case, declare the type as a class.
If you don't know, or are not sure, define the type as a class.
If the type is a small aggregation of primitive types then a struct might offer better performance. However, the benefits are smaller than the risks so, unless you are sure use a class.
So then, how can you be sure, try it and measure the performance with representative data, on representative hardware, compiled in release mode etc. etc. If you really care about performance you'll have to do this anyway.
If you don't want to do this, use a class.

Why are most types in C# inherited from System.Object? [duplicate]

This question already has answers here:
Why does every class in .NET inherit from Object?
(9 answers)
Closed 9 years ago.
I was checking the int and float types in C# and even they have the "ToString" etc, methods meaning they are inherited from System.Object. But Doesn't this cause a performance hit? I understand that they did not make base types like int objects in java because of performance. Doesn't this rule apply to .NET as well? And if it does, then does that mean .NET is slower than Java? But practically that's not true because the programs i have made in C# run way better than those I made in Java. So is there something I don't understand here?
It's very important to understand the differences between value types and reference types. The core of the difference is what the value of an expression of the type is.
Consider:
int x = 10;
SomeClass y = new SomeClass();
Here, the value of x really is 10 - the bits for 10 end up in the memory associated with the variable x.
The value of y is a reference - a way of getting to a separate object in memory.
The difference becomes very important when you use assignment, particularly with mutable reference types:
int x1 = 10;
int x2 = x1;
SomeClass y1 = new SomeClass();
SomeClass y2 = y1;
y1.SomeProperty = "Fred";
Console.WriteLine(y2.SomeProperty);
In both cases, the value of the variable is copied in the assignment - so x2's value is 10; y2's value is a reference to the same object. So when the object's data is modified via the property in the penultimate, you can still see that difference via y2.
You would rarely write z1.SomeProperty = ... when z1 is a variable of a value type, as most value types are immutable. (You can't change the value of the data itself - you have to assign a new value to the variable explicitly.) If you did, however you wouldn't see any changes via variables which were previously initialized using an assignment z1 because the value would have been copied in that assignment.
I have an article on value types and reference types which goes into all this in more detail.
Now, C# and .NET have a unified type system such that even value types inherit from System.Object. That means you can call all the messages from Object on value type values. Sometimes that requires boxing (converting a value type value into an Object) and sometimes it doesn't... I won't go into all the rules right now. Importantly, if a value type overrides an object method (e.g. ToString, or GetHashCode) the value doesn't need to be boxed to call the method.
While boxing does have a performance penalty, it's typically overstated in my experience. These days with generics, boxing isn't really needed as much as it used to be - but so long as you only use it sensibly, it's unlikely to become a significant performance problem in your application.
EDIT: Regarding games, performance, and learning things a bit at a time...
I've seen lots of people asking questions on a relatively advanced topic without understanding the basics. There's nothing wrong with being a beginner, obviously, but in my view it's really important to learn the basics first, in a "newbie friendly" environment - which I don't think games count as.
Personally I find that console apps are the easiest way of learning most core new concepts - whether that's language features, file IO, collections, web services, threading etc. Obviously for things like "learning Windows Forms" you can't do that with a console app - but it really helps if nothing other than the Windows Forms part is new to you.
So I would strongly advise that you learn the basics of C# - things like how value types and reference types work, how parameter passing works, generics, classes, inheritance etc - before you move onto games. That may sound like extra work, but it's likely to save you time later on. When something doesn't behave as you expect it to, you'll know how the language works, so you can focus on the API behaving differently, etc. Trying to learn one thing at a time makes the whole process smoother, in my experience.
In particular, the performance requirements of games mean that sometimes it's worth writing very non-idiomatic C#. Things like preallocating objects and reusing them where you'd normally create new objects... even creating mutable structs which I'd pretty much never do in normal development. In the critical game loop, boxing or creating any objects at all may be a bad idea - but that doesn't mean these things are "expensive" in the normal frame of reference. It's really important that you understand when these things are appropriate, and when they're not... and if you start with games development, you'll get an imbalanced view of these things, IMO. You'll also potentially try to micro-optimize areas where you really don't need to - but if you have a solid grounding in C# and .NET to start with, you'll be in a better position to get everything in perspective.
As long as all objects appear to be derived from System.Object, then for all practical purposed they are derived from System.Object. Underneath the hood things are optimized into perfection so that an int is just a four-byte int most of the time but it's an object when it needs to be an object. That's what boxing is all about.
The compiler and the run-time both work very, very hard to make sure that primitive types are not overburdened with a lot of excess baggage in size or function. At the same time, all rules needed to meet the C# specification and the object hierarchy are ensured. Sometimes the compiler takes shortcuts, sometimes the run-time does the work.
One advantage of having a common base class means that you could write a method like
public void DoSomething(Object object)
{
....
}
and essentially pass in anything.
Not sure about the performance aspect though.
EDIT: To clarify my position on boxing: Jon said it well when he asked me to point out: "[boxing is] as expensive as creating any other small object". So, I don't mean to overstate the performance impact. However, I do intent to arm intelligent readers with the information they need to make smart decisions based on their individual circumstances.
EDIT: OK, so if you want to be technical, I retract my previous statement. From C# ECMA standard: "All value types implicitly inherit from class object. It is not possible for any type to derive from a value type, and value types are thus implicitly sealed (§17.1.1.2)." (C# ECMA Standard Page 130) HOWEVER... It's my understanding that the thrust of the OP's question is really in relation to PERFORMANCE and how the types are treated under the hood in .NET. To that point: Value Types ARE treated differently from Reference Types - and simple types (int, float, etc) are stored and operated upon in an efficient manner. When they ARE treated like Objects, you pay an expensive performance cost (as the OP suspects). The moral of this story is, for me, and hopefully maybe someone else, is to AVOID BOXING - which, in practical terms, means Value Types ARE different from Object... take my answer as you may.
You are mistaken. System.Integer and System.Float are not subclasses of System.Object. They are what's referred to as "Value Types".
you can see this is true in the documentation: http://msdn.microsoft.com/en-us/library/system.int32.aspx which shows that Int is a "struct".
This article discusses the topic in detail: http://msdn.microsoft.com/en-us/library/34yytbws%28v=vs.71%29.aspx
You should definitely read that last one if you're interested in this.
In regards to your broader question, "Why are most types in C# inherited from System.Object", you'll find there is nothing unique about this. Java has java.lang.Object, Objective-C has NSObject, etc. etc. The distinction between value types and reference types is nearly universal. I'm not sure I really need to get into the long-winded answer to that here, because I think pointing out the difference, and the article about value types in C#, has already probably answered your question.
To clarify everyone else's questions about boxing, etc.: http://msdn.microsoft.com/en-us/magazine/cc301569.aspx

How to calculate how big a struct or class is?

I've been told I should only use structs when they are less than 16 bytes. If bigger, it would be more optimal to use a class.
I was wondering, how do I work that out?
Do I just add up all of the fields that are in the struct?
For example, if this struct
public struct Struct1
{
int int1;
}
Then given it's got one integer and one int is 32 bits, is it then four bytes?
What about if I have lots of methods in this struct though? Would the method add to the size of the struct?
Only non-static variables use up space, methods don't. For example, your struct that you made there is four bytes big, because it is the size of an int.
You can also calculate the size using Marshal.SizeOf(GetType((Struct1)).
Unless you have memory critical applications, or have some special reasons you need a struct, I would suggest always using a class.
Use the built-in sizeof keyword.
EDIT: Nevermind, only available when dealing with unsafe code. (also, only really useful then too)
I would not solely think about the 16bytes limit when deciding whether to use a class or struct. I would look at the semantics first. If you need to create an entity, I would use a class. If you need to create a value type, I would first think of a struct.
Your best bet: When should I use a struct instead of a class?
MSDN has the answer: Choosing Between Classes and Structures. 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.
Make this analysis, and further, the decision, based on any such conclusion at design-time - not runtime, since you can't change the type definition at that point.
In order for you to work out the sizes, I'll just point you forward to a very interesting article (from 2005 MSDN magazine, but still relevant) which discusses the allocation of objects in the CLR, with reference to sizes, offsets et cetera; this will educate you more than enough to be able to determine what you need and also enable you to research further into what you're still unsure of:
http://msdn.microsoft.com/en-us/magazine/cc163791.aspx

When exactly do I use a struct (Dont tell me when I want things to be allocated on a stack) [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 12 years ago.
A lot of times the answer is merely when I want things to be allocated on a stack instead of the heap.. assuming I dont know what the stack and the heap are (and please dont try to explain it here), when exactly should I be using structs instead of classes?
Here is the answer I've been giving out, but please tell me if I'm wrong or falling short of a better answer:
I create structs usually when I have enums that I want to add more data to. For instance, I might start with a simple enum:
public enum Colors { Blue, Green, Red }
Then if I need to store more aspects of this data I go to structs:
public struct Color
{
string Name;
int HexValue;
string Description;
}
public class Colors
{
public static Color Blue;
public static Color Red;
public static Color Green;
static Colors()
{
Blue = new Color("Blue", 1234, "A light blue"
}
}
The point is... similar to enums, I use structs just when I want to declare a bunch of types.
struct vs class in .NET
The real time to use a struct is when you want value type like properties. Value types behave very differently from reference types, and the difference can be shocking and bug inducing if you aren't aware. For example a struct is copied into (and out of) method calls.
The heap vs stack isn't a compelling argument to me. In a typical .NET app, how often do you care about where the object lives?
I very rarely use structs in .NET apps. The only place I've truly used them was in a game where I wanted value type like properties for objects like vectors and such.
struct vs class in C++
This is a much simpler question to answer. structs and classes in C++ are identical to each other with only one minor difference. Everything in a C++ struct is public by default, where as everything in a C++ class is private by default. That is the only difference.
Simplistically, structs are for data, classes are for data and the manipulations of those data.
well in C++ land, you can allocate a struct (or class) on the stack or the heap... I generally use a struct when the default public access to everything is useful and class when I want to encapsulate... I also use structs for functors that need state.
You have this labelled with C#, C++ and "language-agnostic". The fact is though, the difference between structs and classes in C# and C++ are completely different, so this is not a language-agnostic question.
In C++ class is syntactic sugar for struct with different default visibility. The reason is that C had a struct and only had "public" visibility (indeed, it's not even a fully meaningful statement in C, there's no such thing as OO-style information hiding in C).
C++ wanted to be compatible with C so it had to keep struct default to everything visible. C++ also wanted to follow good OO rules, in which things are private by default, so it introduced class to do exactly the same, but with different default visibility.
Generally you use struct when you are closer to C-style use; no or relatively simple member functions (methods), simple construction, ability to change all fields from the outside ("Plain Old Data"). class is generally used for anything else, and hence more common.
In C# a struct has value semantics while a class has reference semantics (in C++ both classes and structs have value semantics, but you can also use types that access them with reference semantics). A struct, as a value-type is self-contained (the variable contains the actual value(s) directly) while a class, as a reference type refers to another value.
Some other differences are entailed by this. The fact that we can alias reference types directly (which has both good and bad effects) comes from this. So too do differences in what equality means:
A value type has a concept of equality based on the value contained, which can optionally be redefined (there are logical restrictions on how this redefinition can happen*). A reference type has a concept of identity that is meaningless with value types (as they cannot be directly aliased, so two such values cannot be identical) that can not be redefined, which is also gives the default for its concept of equality. By default, == deals with this value-based equality when it comes to value types†, but with identity when it comes to reference types. Also, even when a reference type is given a value-based concept of equality, and has it used for == it never loses the ability to be compared to another reference for identity.
Another difference entailed by this is that reference types can be null - a value that refers to another value allows for a value that doesn't refer to any value, which is what a null reference is.
Also, some of the advantages of keeping value-types small relate to this, since being based on value, they are copied by value when passed to functions.
Some other differences are implied but not entailed by this. That it's often a good idea to make value types immutable is implied but not entailed by the core difference because while there are advantages to be found without considering implementation matters, there are also advantages in doing so with reference types (indeed some relating to safety with aliases apply more immediately to reference types) and reasons why one may break this guideline - so it's not a hard and fast rule (with nested value types the risks involved are so heavily reduced that I would have few qualms in making a nested value type mutable, even though my style leans heavily to making even reference types immutable when at all practical).
Some further differences between value types and reference types are arguably implementation details. That a value type in a local variable has the value stored on the stack has been argued as an implementation detail; probably a pretty obvious one if your implementation has a stack, and certainly an important one in some cases, but not core to the definition. It's also often overstated (for a start, a reference type in a local variable also has the reference itself in the stack, for another there are plenty of times when a value type value is stored in the heap).
Some further advantages in value types being small relate to this.
Therefore in C# a struct when you are solely concerned with value-semantics and will not want to alias (string is an example of a case where value-semantics are very important, but you would want to alias, so it is a class to make it a reference-type). It's also a very good idea for such types to be immutable and an extremely good idea for such types to have fields that total to less than 16bytes - for a larger struct or a struct that needs to be mutable it may well be wise to use a class instead, even if the value-semantics make struct your first choice.
In C++, technically it doesn't matter. You could use struct for polymorphic object and class for PODs. The language wouldn't care, though your coworkers may plot a bloody revenge. Aside from default access, there's no difference between class and struct.
Ultimately, the most important consideration is that you pick a coding style, and apply it consitantly. Maybe that means everything is classes, or maybe PODs are structs. You need to decide for yourself, taking in to consideration any coding practices applied by whomever you work for.
As for myself, I only use structs if the object has only public members and no virtuals. They might have data only or data and methods. Typically I use structs for buckets of data that may or may not have simple operations associated with them, usually to convert from one type to another. Hence they may also have constructors.
When to use struct...
When you want object to behave as a value type
When the required size of object is <=16 bytes roughly.
A struct is actually exactly the same thing as a class - with one difference: in a class, everything is private by default while in a struct, everything is public by default!
struct Color
{
string Name;
private:
int HexValue;
};
would be the same as
class Color
{
int HexValue;
public:
string Name;
};
I would say , use stack when your data is smaller in size and you don't want a few thoushands of this object because it can hurt ou back a lot because as already mentioned that value types are copied by nature so pasing few thoushands of objects which is copied by value is not a good idea also.
Second point , i would like to include is when you only want data for most of the time and data is numeric most of the time , you can use stack.

Which is best for data store Struct/Classes?

We have seen lots of discussion in SO regarding the class vs struct in c#. Mostly ended with conclusions saying its a heap/stack memory allocation. And recommending to use structs in small data structures.
Now I have a situation to decide the simple data store among these two choices. Currenlty in our application we have thousands of classes, just acts as simple data stores (only exposed public fields) and they passed among different modules and services.
As per my understanding, I felt it's better to move ahead with struct instead classes for the performance reasons. Because these are simple data structures only act as data stores.
Before proceeding with this, I need some expert advice from the people who have experienced this struggle.
is my understanding correct?
I have seen most ORMs have classes as data stores. So I doubt there should a reason to go ahead with classes instead structs. what would that be?
I would make the choice based on the following criteria
reference type vs value type semantics. If 2 objects are only equal if they are the same object, it indicates reference type semantics => class. If the value of its members defines equality (e.g. 2 DateTimes are equal if both represent the same point in time even if they are 2 distinct objects), value type semantics => struct
Memory footprint of the object. If the object is huge and frequently allocated, making it a struct would consume the stack much faster, hence I'd rather have it as a class. On the contrary, I'd rather avoid the GC penalty for small value types; hence make them a struct.
can you make the object immutable? I find structs great for 'value objects' - from the DDD book.
Would you face some boxing-unboxing penalty based on the usage of this object? If yes, go for class.
A pretty cool, not so well known advantage of Structs over Classes is that there is an automatic implementation of GetHashcode and Equals in structs.
That's pretty useful when keys are required for dictionaries
The struct implementation of GetHashcode and Equals is based on the binary content of the struct instances + reflection for the reference members (like String members and other instances of classes)
So the following code works for GethashCode/Equals :
public struct Person
{
public DateTime Birthday { get; set; }
public int Age{ get; set; }
public String Firstname { get; set; }
}
class Program
{
static void Main(string[] args)
{
Person p1 = new Person { Age = 44, Birthday = new DateTime(1971, 5, 24), Firstname = "Emmanuel" };
Person p2 = new Person { Age = 44, Birthday = new DateTime(1971, 5, 24), Firstname = "Emmanuel" };
Debug.Assert(p1.Equals(p2));
Debug.Assert(p1.GetHashCode() == p2.GetHashCode());
}
}
Both assertions succeed when Person is a struct
Both assertions fail if Person is a class instead of a struct
Reference :
https://msdn.microsoft.com/en-Us/library/2dts52z7%28v=vs.110%29.aspx
Regards, best coding
structs should be defined immutable where in classes should not. If you think your objects are going to be small and immutable you can go ahead with making them structs or else let them be classes.
I can never really seem to remember, exactly how structs are different, but they are. In subtle ways. In fact, sometimes they come and bite you.
So. Unless you know what you are doing, just stick to classes.
I know this sounds a little newbie. I know I should right now go and look up the differences and display them here - but that has already been done by others. All I'm saying is that adding a different type of objects creates a semantical burden, a bit of extra complexity that you are wise to consider carefully.
If I remember correctly, one of the biggest problem is the value semantics of structs: Passing them around will result in different objects (as they get passed by value). If you then change some field in one place, beware that in all other places the field did not get changed! That is why everyone is recommending immutability for structs!
EDIT: For the case you are describing, structs won't work!
A class object has the advantage that it's possible to pass around a reference to it, with the scope and lifetime of such a reference being unlimited if it reaches outside code. A struct has the advantage that while it's possible to pass around short-lived references to them, it's not possible to pass around perpetual promiscuous references. This helps avoid having to worry about whether such references exist.
Some people have suggested that data holders which are mutable should not be structs. I emphatically disagree. Entities which exists for the purpose of holding data should, in many cases, be structs, especially if they are mutable. Eric Lippert has posted many times that he considers mutable value types evil (search under tags "mutable" and "struct"). It is certainly true that .net allows certain things to be done with mutable structs which it shouldn't, and doesn't conveniently allow some things that it should, but POD ("Plain Old Data") structs which have no mutating methods, but instead expose their entire state via public fields, have a very useful consistency in their behavior which is not shared with any other data type. Using a POD struct may confuse someone who isn't familiar with how they work, but will make the program much more readable by anyone who does.
Consider, for example, the following code, assuming EmployeeInfoStruct contains nothing but value types and immutable class types like String:
[employeeInfoStruct is a struct containing the following field]
public Decimal YearlyBonus;
[someEmployeeContainer is an instance of a class which includes the following method]
EmployeeInfoStruct GetEmployeeInfo(String id); // Just the signature--code is immaterial
[some other method uses the following code]
EmployeeInfoStruct anEmployee = someEmployeeContainer.GetEmployeeInfo("123-45-6789");
anEmployee.YearlyBonus += 100;
Eric Lippert complains that the above code will alter the value in anEmployee, but that change won't have any effect on the container. I would suggest that's a good thing--anyone who knows how structs work could look at the above code and know writes to a struct variable will affect that variable, but won't affect anything else unless the program later uses some other method (perhaps SetEmployeeInfo) to store that variable someplace.
Now replace EmployeeInfoStruct with EmployeeInfoClass, which has a read/write property of type YearlyBonus. Using just the information above, what can one say about the the relationship between writes to someEmployeeContainer and anEmployee? Depending upon the implementations of anEmployee's class (which, unless EmployeeInfoClass is sealed, might or might not actually be EmployeeInfoClass) and someEmployeeContainer, the relationship between the objects could be anything. Writes to one might:
Have no effect on the other
Update the other in 'natural' fashion
Corrupt the other in some arbitrary way
With structs containing nothing but fields of either value types or immutable classes, the semantics are always going to be #1. One doesn't have to look at the code for the struct itself, nor the code of the container, to know that. By contrast, if the anEmployee.Salary or someEmployeeContainer.GetEmployee is virtual, it's impossible to really know what the semantics will be.
It's important to note that, if structs are large, passing them by value or returning them from functions can be expensive. It's generally better to pass large structs as ref parameters when possible. Although the built-in collections really don't do a good job of facilitating such usage, it can make using a hundreds-of-bytes struct cheaper than using a class.
The comment about structs being immutable is correct. And this is where it can bite you. You can define structs with field setters, but when you change a field value a new instance is created. So if you hold a reference to the old object it will still reference the old value. I don't like using mutable stucts for this reason as this can produce subtle and complex bugs (especially if you use complex compound statements).
On the other hand, there are lots of good reasons for using classes with immutable state also (think string).
I remember one advice given on MSDN that struct should not be larget than 16 or 21 bytes. Looking for the link, but can't find it yet.
The main implication was that once you have a string in your data type - make it a class without thinking. Otherwise the struct shouldn't hold much.
I think you have the right idea. Structs are made to mimic data-types. They are value driven not reference based. If you look at the MSDN documentation for most of the base data classes (int, double, decimal, ect.) they are all based on structs. That being said however, structs should not be overused for that very same reason. Room to store all everything in that struct is allocated as soon as it is instantiated, where as classes just allocate room for a reference to everything inside. If the data is in small enough chunks where this is not a problem than structs are the way to go. If this is an issue go with classes. If you don't know than it might just be best to stick with what you are familiar with.
If you have low latency requirements and A LOT of objects slow garbage collections can be a problem. In that case struct can be very helpful because the garbage collector does not need to scan through a hierarchy of value types if the value types does not contain any reference types.
You can find a benchmark here: http://00sharp.wordpress.com/2013/07/03/a-case-for-the-struct/

Categories

Resources