I have an exam question from a past paper that I'm trying to answer:
Discuss variables of type primitive, reference and static in the context of a programming language. Give suitable examples [8].
The answer I have so far is:
A primitive type is an object which the language has given a predefined value. These types include int, bool and float. Reference type objects refer to these primitive types in a particular sequence when instantiated. Examples of these are strings and arrays. The static keyword, when assigned to a variable, means that there is only one instance of this variable and the value assigned applies to all references of the variable.
I'm fairly new to programming so I don't know if this is exactly right, so if anyone could give me some tips on how to improve the mark I would get for this question I'd greatly appreciate it.
A primitive type is an object which the language has given a
predefined value
Why? Even references can have predefined values as noted. For primitive (built in) types you may want to say these are types that a language provides built in support for. What your instructor might be glad to hear about is if you say that most primitive types are also value types in C# and you might want to discuss value types semantics (e.g., value type variable directly contains value - whereas a reference variable just contains an address to some object in memory).
About reference types again you may say that a reference variable doesn't contain the value or object directly - rather just a reference to it. Now again you may want to discuss reference semantics. For example if you have two reference variables pointing to same object - and you change the object from one reference change will be visible from another reference too - because both references point to same object. This is not the case with value types. If you assign same value type object to two different value type variables and change one variable - this change will not be visible in the second value type variable because each of them holds the value directly (e.g. each will have its own copy of the value type variable it was assigned to).
Static types you have already described.
You are on the right track for sure, but you are missing some fundamental concepts about these. Also, the 3 are not mutually exclusive:
A primitive type is simply a syntax shortcut defined by the compiler for Framework Class Library or FCL types.
A reference type is a pointer that represents an instance of a class. The objects they point to are allocated on the heap and the value of the variable is the memory address of that object rather than the class itself.
Static is not a type at all, but really defines where and when fields, properties, methods, and classes can be used. A static variable lives on the class rather then an instance. A static constructor is called the first time you access the class. A static method can be called from the class definition. That explains the persistence you see on static variables as you create and destroy them.
The answer to that question, in my opinion -- has not a thing to do with OOP and everything to do with the compiler and microprocessor.
The simplest and most accurate definition of the term that subsumes all of the qualities of a primitive type -- as I understand it -- is:
A primitive type must fit into the register used for operations on it -- IOW, in an X86 system -- the Accumulator.
So, primitive types are limited to the size of the Accumulator and can be operated upon by native processor instructions. (Basic math and Boolean/bit-shifting operations). Yes, it fits into heap memory and on the stack, but those are still essentially 8-bit entities and the registers are not.
OOP languages do not use primitive types for their managed memory processes, they use structures that mimic primitive types. (Even in .NET, when you use the keyword int -- it uses System.Int32 to wrap that.)
Related
As Int32 is a struct which means it is a System.ValueType (which inherits System.Object), when I pass an Integer to a function which expects Object, why should CLR box it?
Does CLR assumes that Object is always a reference type?
It is a bit confusing to think that ValueType "is" an Object but when you have to pass it "as" object, you need box it...
Am I the only one who is wondering about this?
It's not that a type derived from Object is always a reference type, but rather that a variable of type Object always contains a reference. Suppose you wanted to store the actual value in the Object; how then would you decide how big the Object value would need to be?
A variable of a compile-time-known value type has a known size for which space can be allocated, but an Object, being able to 'contain' any value type, cannot be sized in advance. One logical solution then is to have the Object variable contain a special type of reference to a boxed object, whereby the size of the 'box' is allocated dynamically depending on what type is being boxed.
Some slightly more technical notes:
Another solution to the above problem would be to treat the Object as a reference to an arbitrary location in memory, which would prevent having to create a boxed copy. This is how it's done in C, where you can create a pointer to a value on the stack, for instance, then pass that to another function for use. This can be quite dangerous though, as what happens, for instance, if the function decides to keep that pointer around and use it at some undefined later time. Since the call stack has changed, that pointer is now pointing to something entirely different than was originally intended and writing to it will almost certainly have disastrous side effects.
Part of the goal of .NET, as a managed runtime, is to provide a 'safe' environment where these particular kinds of failures can't happen. Part of that trade-off is disallowing persisted direct references to stack memory, necessitating boxing when you want to 'persist' the contents of a value type in a variable containing a reference. This used to be a performance problem with collections in .NET 1.1, but the addition of Generics in .NET 2.0 meant that boxing was far less common an occurrence.
What is the definition of a value class and reference class in C#?
How does this differ from a value type and reference type?
I ask this question because I read this in the MCTS Self-Paced Training Kit (Exam 70-536). Chapter 1, Lesson 1, Lesson review 4 :
You need to create a simple class or
structure that contains only value
types. You must create the class or
structure so that it runs as
efficiently as possible. You must be
able to pass the class or structure to
a procedure without concern that the
procedure will modify it. Which of the
following should you create?
A reference class
B reference structure
C value class
D value structure
Correct Answer: D
A Incorrect: You could create a
reference class; however, it could be
modified when passed to a procedure.
B Incorrect: You cannot create a
reference structure.
C Incorrect: You could create a value
class; however, structures tend to be
more efficient.
D Correct: Value structures are
typically the most efficient.
You may be thinking of C++/CLI which, unlike C#, allows the user to declare a "value class" or a "ref class."
In C#, any class you declare will implicitly be a reference class - only built-in types, structs, and enums have value semantics.
To read about value class in C++/CLI, look here:
http://www.ddj.com/cpp/184401955
Value classes have very little functionality compared to ref classes, and are useful for "plain old data"; that is, data which has no identity. Since you're copying the data when you assign one to another, the system provides you with a default (and mandatory) copy constructor which simply copies the data over to the other object.
To convert a value class into a reference class (thereby putting it on the garbage-collected heap) you can "box" it.
To decide whether a class you are writing is one or the other, ask yourself whether it has an identity. That usually means that it has some state, or has an identifier or a name, or a notion of its own context (for example a node pointing to nearby nodes).
If it doesn't, it's probably a value class.
In C#, however, value classes are declared as "structs".
See the overview on the subject, but seriously follow the msnd links and read the full Common Type system chapter of it. (You could also have asked in a comment in the first, question)
Value types are passed by value, while reference types are passed by reference.
Edit: value/reference classes
There is no concept of a 'value class' or 'reference class' in C#, so asking for its definition is moot.
Value types store the actual data while reference types store references to the data. Reference types are stored dynamically on the heap while value types are stored on the stack.
Value Types: http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx
Reference Types: http://msdn.microsoft.com/en-us/library/490f96s2.aspx
When you refer to a value type (that is, by using its name), you're talking about the place in memory where the data is. As such, value types can't be null because there's no way for the memory location to say "I don't represent anything." By default, you pass value types by value (that is, the object you pass in to methods doesn't change as a result of the method's execution).
When you use a reference type object, you're actually using a pointer in disguise. The name refers to a memory location, which then references a place in memory where the object actually lives. Hence you can assign null to a reference type, because they have a way of saying "I point to nowhere." Reference types also allow the object to be changed as a result of methods executing, so you can change myReferenceObject's properties by passing it into a method call.
Reference types are passed to methods by reference and value types by value; in the latter case a method receives a copy of the variable and in the former it receives a reference to the original data. If you change your copy, the original does not change. If you change the original data you have a reference to, the data changes everywhere a reference to the data is changed. If a similar program to your C# program was created in C, generally reference types would be like data using pointers and value types would be normal data on the stack.
Numeric types, char, date, enumerations, and structures are all value types. Strings, arrays, delegates and classes (i.e., most things, really) are reference types.
If my understanding is correct, you can accomplish a "value class", or immutable class, through the use of readonly member variables initialized through the constructor. Once created, these cannot be changed.
I don't understand it...
Why do they need a common base?
The question presupposes a falsehood. They don't need a common base type. This choice was not made out of necessity. It was made out of a desire to provide the best value for the customer.
When designing a type system, or anything else for that matter, sometimes you reach decision points -- you have to decide either X or not-X. Common base type or no common base type. When that happens you weigh up the costs and the benefits of X to determine the net value, and then you weigh up the costs and the benefits of not-X to determine the net value, and you go with the one that was higher value. The benefits of having a common base type outweigh the costs, and the net benefit thereby accrued is larger than the net benefit of having no common base type. So we choose to have a common base type.
That's a pretty vague answer. If you want a more specific answer, try asking a more specific question.
I think, mainly in order to have a type to refer to any object. An argument of type object could be a primitive type, a struct, a reference type, just anything. It is important to have such a type.
Then there are some common members that are implemented by every type, like Equals, ToString, GetHashCode. This could indeed be a common interface as well, but then you wouldn't inherit a default implementation.
Because its in the spec:
8.9.9 Object type inheritance
With the
sole exception of System.Object, which
does not inherit from any other object
type, all object types shall either
explicitly or implicitly declare
support for (i.e., inherit from)
exactly one other object type. The
graph of the inherits-relation shall
form a singly rooted tree with
System.Object at the base; i.e., all
object types eventually inherit from
the type System.Object.
There are several benefits to this design approach.
Some reasons why many / most are:
To provide common members such as Equals, Finalize, GetHashCode, ToString....
To help with boxing....
Java and C# took a different approach to this. It's mainly to do with performance.
If you imagine that every object can be nullable, then it has to be a pointer to a value, which can be changed to a pointer to null. Now this means that for every object you need at least a pointer and a chunk of memory to store the value.
Java has the concept of a primitive value, which is NOT an object. It doesn't have a pointer and it isn't nullable. This breaks the OOP paradigm but performance wise makes sense.
C# (or more correctly the CLR + BCL) attempted a good compromise, the ReferenceType and ValueType derivations. Anything that derives from ValueType are treated like primitives to the CLR, avoiding having an object reference. However this value can still be treated like an object via boxing, allowing you to have the performance benefits of primitive types but allowing everything to be treated like an object.
The real key difference between these things is the semantics of passing parameters to methods. If everything is an object, then you are passing references to the object, i.e the object can be changed by passing it to a method. Primitives and C# value types are passed by value, so they are effectively copied into the method call and the original value is unchanged.
It's the standard story of development. Try and get it right first, then see if you can optimise it later once you see the bottlenecks. Having pass by value semantics also allow you to prevent coding mistakes from mutability. (eg. passing a class vs a struct in C#)
ToString. For example.
Useful for Boxing and Unboxing
see reference
Every object in .NET shares common properties and methods. However, these are then divided into two categories: value types and reference types. Value types (ie, int) are stored on the stack, Reference types (ie, your custom class) are stored on the heap. Reference types store a reference to the actual data (thats on the heap). Value types directly contain their data.
You can read more over at MSDN:
http://msdn.microsoft.com/en-us/library/system.object.aspx
As a side note to other "answers" a struct is a value type, that also inherits from object.
Maybe the answer is that its assumed that we are programming object-oriented style/paradigm? A ball is an object. A sword is an object. An employee is an object. A purchase order is an object.
Some companies design their .NET (or Java or Ruby or PHP) applications to inherit from a common base class, so that they can all be treated the same way in their system. If I remember correctly from back in my old Java days... all EJBs share the same base class so that they can be managed and identified uniformly.
i am a java programmer and i know in java objects are stored on heap. Just for curiosity wanted to where does objects reside in c#.
For reference types : on the heap
For value types : on the stack for local variables and method parameters, or on the heap for members of a reference type
The C# language doesn't specify where an object or a value should be stored. It simply defines the semantics of reference types and value types.
Microsoft .NET CLR stores values (instances of value types) contained of local variables on stack and instances of reference types (objects) and non-local value types on the heap. However, as stated previously, other implementations of the C# language are free to store things as they wish as long as they conform to value and reference semantics defined by the C# Language Specification.
detailed explaination,
C# Heap(ing) Vs Stack(ing) in .NET: Part I
By Matthew Cochran January 14, 2006 http://www.c-sharpcorner.com/UploadFile/rmcochran/csharp_memory01122006130034PM/csharp_memory.aspx
Objects are stored on heap in C# too.
Reference types stored on managed heap.
Value types by default stored on stack.
Value types also can stored on heap in several cases:
During boxing (casting value type to interface, downcasting value type to object etc).
If value type is a member of reference type
If value type uses in closure
Allegedly, the native code is shared for instantiated generic types when it is instantiated with a reference type, but not for value types.
Why is that? would someone explain the in-depth details?
To make more concrete:
class MyGenericType{
}
MyGenericType<string> and MyGenericType<Shape>
will have only one code generated, whereas
MyGenericType<int> and MyGenericType<long>
will NOT, hence it begs the question if using reference types is more efficient --
MyGenericType<int> vs. MyGenericType<SomeIntegerWrapper>
Thanks
First, to correct a fallacy in the question, int and System.Int32 are synonymous. MyGenericType<int> and MyGenericType<Int32> are exactly the same type.
Secondly, to address the question (and slightly expand on Mehrdad's answer): consider what the CLR needs to know about a type. It includes:
The size of a value of that type (i.e. if you have a variable of some type, how much space will that memory need?)
How to treat the value in terms of garbage collection: is it a reference to an object, or a value which may in turn contain other references?
For all reference types, the answers to these questions are the same. The size is just the size of a pointer, and the value is always just a reference (so if the variable is considered a root, the GC needs to recursively descend into it).
For value types, the answers can vary significantly. For instance, consider:
struct First
{
int x;
object y;
}
struct Second
{
object a;
int b;
}
When the GC looks at some memory, it needs to know the difference between First and Second so it can recurse into y and a but not x and b. I believe this information is generated by the JIT. Now consider the information for List<First> and List<Second> - it differs, so the JIT needs to treat the two differently.
Apologies if this isn't as clear as it might be - this is somewhat deep stuff, and I'm not as hot on CLR details as I might be.
Technically, at a lower level, all reference types are pointers and therefore, have the same size and characteristics. There is no need for the runtime to build separate native code for reference types. Value types can have different sizes, so a single native code cannot deal with all of them.