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

I tested int and float types in C #, even if they have "ToString" etc., which means they inherit from System.Object. But does this not lead to a blow? I understand that they did not make basic types such as int objects in java due to performance. Does this rule apply to .NET? And if so, does that mean .NET is slower than Java? But this is practically not the case, because the programs I made in C # work much better than the ones I did in Java. So what I do not understand here?

+7
source share
4 answers

It is very important to understand the differences between value types and reference types. The core of the difference is that the value of the type expression.

Consider:

int x = 10; SomeClass y = new SomeClass(); 

Here, the x value is really 10 - bits for 10 end in the memory associated with the variable x .

The y value is a reference - a way to access a single object in memory.

The difference becomes very important when you use assignment, in particular 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 - therefore, the value of x2 is 10; The value y2 is a reference to the same object. Therefore, when the data of an object is changed using the property in the penultimate, you can still see this difference through y2 .

You rarely write z1.SomeProperty = ... when z1 is a value type variable, since most value types are immutable. (You cannot change the value of the data itself - you need to explicitly assign the new value to the variable.) If you did, however, you will not see any changes through the variables that were previously initialized using the z1 assignment because the value would be copied to that assignment.

I have an article on value types and reference types that goes into detail in all of this.


C # and .NET now have a unified type system, so even value types inherit from System.Object . This means that you can call all messages from Object by value type values. Sometimes this requires boxing (converting a value of type value to Object ), and sometimes not ... I won’t go into all the rules right now. It is important that if the value type overrides the method of the object (for example, ToString or GetHashCode ), you do not need to specify a value to call the method.

While boxing has a performance limit, it is usually overrated in my experience . These days with generics, boxing is really not needed as much as it was before, but as long as you use it only wisely, it is unlikely to become a serious performance problem in your application.


EDIT: Regarding games, performance, and learning things a little at a time ...

I have seen many people asking questions regarding a relatively advanced topic without understanding the basics. There is nothing wrong with being a beginner, obviously, but in my opinion, it is very important to first learn the basics, in an environment “friendly to beginners,” which I don’t think games are considered so.

Personally, I believe that console applications are the easiest way to learn most of the basic new concepts - be it language features, input / output files, collections, web services, streams, etc. Obviously, for things like “learning Windows Forms,” you can't do that with a console application — but it really helps if nothing but the Windows Forms part is new to you.

Therefore, I highly recommend that you learn the basics of C # - things like how value types and reference types work, how parameter passing, generics, classes, inheritance, etc. work. - before moving on to games. This may sound like extra work, but it will most likely save you time later. When something doesn't behave as you expect, you will know how the language works, so you can focus on the API in different ways, etc. Trying to learn one thing at a time makes the whole process smoother, in my experience.

In particular, performance requirements for games mean that sometimes it's worth writing very non-idiomatic C #. Things like pre-distributing objects and reusing them where you usually created new objects ... even creating volatile structures that I would almost never do in normal development. In a critical game cycle, boxing or creating any objects in general may be a bad idea - but this does not mean that these things are “expensive” in a normal coordinate system. It is really important that you understand when these things are suitable, and when they are not ... and if you start developing games, you will get an unbalanced view of these things, IMO. You can also try to optimize micro-areas where you really don't need it - but if you have solid grounding in C # and .NET for starters, you'll be in a better position to get everything in perspective.

+10
source

While all are displayed , from System.Object , for all practical purposes they are derived from System.Object . Under the hood, everything is optimized to perfection, so int is just four bytes of int most of the time, but it is an object when it should be an object. That's what boxing is about.

The compiler and runtime work very, very difficult to make sure that primitive types are not overloaded with a lot of excess baggage in size or function. At the same time, all the rules needed to comply with the C # specification and object hierarchy. Sometimes the compiler takes shortcuts, sometimes the runtime does the job.

+5
source

One of the advantages of having a common base class means that you can write a method like public void DoSomething (object object) {....}

and, in essence, go through anything.

Not sure about the performance aspect.

0
source

EDIT: To clarify my position on boxing: John said it well when he asked me to point out: "[boxing] is as expensive as creating any other small object." Therefore, I do not want to overestimate the impact of performance. However, I intend to equip smart readers with the information they need to make intelligent decisions based on their individual circumstances.

EDIT: Okay, so if you want to be technical, I undo my previous expression. From the C # ECMA standard: "All value types are implicitly inherited from the class object. It is impossible for any type to be inferred from the value type, therefore value types are implicitly closed (§17.1.1.2)." (C # ECMA Standard p. 130) HOWEVER ... I understand that the OP question is really related to PERFORMANCE and how types are handled under the hood in .NET. At this point: Value types are handled differently from reference types - and simple types (int, float, etc.) are stored and work efficiently. When they are treated as objects, you pay the expensive cost of execution (as the OP suspects). The moral of this story, for me, and hopefully maybe someone else, is to AVOID BOXING, which in practice means that the types of values ​​are different from Object ... take my answer as you can.


You are wrong. System.Integer and System.Float are not subclasses of System.Object. They are called Value Types.

you can see that this is true in the documentation: http://msdn.microsoft.com/en-us/library/system.int32.aspx , which shows that Int is a "structure".

This topic discusses the topic in detail: http://msdn.microsoft.com/en-us/library/34yytbws%28v=vs.71%29.aspx

You should definitely read this last one if you are interested in this.

As for your broader question: “Why are most types in C # inherited from System.Object”, you will find that 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 almost universal. I'm not sure that I really need to get into the long answer to this question, because I think pointing to the difference, and the article on value types in C # probably already answered your question.

To clarify all other questions about boxing, etc.: http://msdn.microsoft.com/en-us/magazine/cc301569.aspx

0
source

All Articles