Is everything in .NET an object?

Please help us settle the controversy of “Nearly” everything is an object (an answer to Stack Overflow question As a novice, is there anything I should beware of before learning C#?). I thought that was the case as everything in Visual Studio at least appears as a struct. Please post a reference, so that it doesn’t become “modern jackass” (This American Life).

Note that this question refers to C#, not necessarily .NET, and how it handles the data under the hood (obviously it’s all 1’s and 0’s).

Here are the comments to “everything is an object”:

  • Eh, no, it’s not. – Binary Worrier
  • I’d like an example… – scotty2012
  • isn’t everything derived from the
    base type Object? – rizzle
  • Most things are objects… – Omar
    Kooheji
  • Value types, ints, doubles, object
    references (not the objects them
    selves) etc aren’t objects. They can
    be “boxed” to look like objects (e.g.
    i.ToString()) but really they’re
    primitive types. Change the entry to
    “NEARLY everthing is an object” and
    I’ll remove the downvote – Binary
    Worrier
  • I appreciate the clarification. I
    think the lowest level that you can
    interact with, say an int, in C# is
    as a struct, which isn’t an object? –
    http://msdn.microsoft.com/en-us/library/ms173109.aspx
    – rizzle
  • Doesn’t Int32 inherit from ValueType
    which inherits from Object? If so,
    despite the behavior, an int is an
    object. – Chris Farmer
  • No, the boxed type for int inherits
    from ValueType, which inherits from
    Object. They’re not objects in the
    traditional sense because a) an int
    isn’t a reference to an int, IT IS
    the int. b) ints aren’t garbage
    collected. If you declare an Int32,
    then that int is 4 bytes on the
    stack, end of story – Binary Worrier

Definition of object: “Object” as a inheritor of class System.Object vs. “object” as an instance of a type vs. “object” as a reference type.”

41 thoughts on “Is everything in .NET an object?

  1. user

    Rizzle! I was just about to post this as a question, to see what the community says. P.S. I'd wait to see what Jon Skeet or Marc Gravell say before selecting an answer.

    Reply
  2. user

    @annakata – There is an answer for this, its either yes or no. It is not a subjective question. It seems like their is some debate about what the correct answer is, but by clear, I think Rich meant that the question isn't subjective.

    Reply
  3. user

    Please, clarify the question. "Object" as a inheritor of class System.Object vs. "object" as an instance of a type vs. "object" as a reference type.

    Reply
  4. user

    Everything in C# are value types. And the rest are objects, including value types(when they are boxed). Value types are boxed to object by the compiler(compilation time, not runtime) only when the compiler infers from your code that you want all the good stuff of object unification brings. …

    Reply
  5. user

    … E.g. .ToString(), passing to Collections, passing to params, etc. Simply put, you can just say, everything is an object 😉

    Reply
  6. user

    @rizzle and @Binary Worrier – I second that request, how do you define an object? Are you referring to the System.Object class (in which case the answer is yes)?

    Reply
  7. user

    ..And this is what I mean when I say it's unclear – the answer is both yes and no, as illustrated by Daniel Schaffer. The parameters of the question itself are subjective.

    Reply
  8. user

    I don't see how this should be closed – it seems to be a perfectly valid (if too unspecific) question, especially as there does appear to be some confusion on the topic.

    Reply
  9. user

    Thanks everyone for the discussion. I originally asked this Q because i didn't know about reference types and was trying to reconcile the different behavior of some types in .net. I sure do know about them now!

    Reply
  10. user

    To summarize all the answers, there are two meanings of "object" in C#. One meaning has to do with the fact that members of ValueType and of Object can be called on "value types". By this definition, "value types" are "objects". The second meaning comes from C# spec, which explicitly refers to "instances of reference types" as being "objects", excluding value types. Both meanings are valid viewpoints, though they reach opposite conclusion re value types. A third POV is that a "boxed" value type is an "object" but the "raw" value is not.

    Reply
  11. user

    A little late to the party, but I came across this in a search result on SO and figured the link below would help future generations:

    Eric Lippert discusses this very thoroughly, with a much better (qualified) statement:

    The way to correct this myth is to simply replace “derives from” with “is convertible to”, and to ignore pointer types: every non-pointer type in C# is convertible to object.

    The gist of it, if you hate reading well-illustrated explanations from people that write programming languages, is that (pointers aside), things like Interface, or generic parameter type declarations (“T”) are not objects, but are guaranteed to be treatable as objects at runtime, because they have a definite instance, that will be an Object. Other types (Type, Enum, Delegate, classes, etc.) are all Objects. Including value types, which can be boxed to object as other answers have discussed.

    Reply
  12. user

    This a discussion of two worlds: language and memory.

    To me language is like a layer of abstraction and the term object belongs to this level of abstraction. I don’t see a point in talking about objects in terms of memeory organisation and if you do use the “object” term when talking about memory you actually are borrowing this term from a different layer of abstraction. Thus you shouldn’t forget where it came from.

    If we’re talking about C# I don’t undestand why someone would use memory organisation as an argument. Of course if I would answer this question to someone I would say “Yes, in C# everything is an object, but you also should know that under the hood it may work differently depending on….”

    This may start an interesting argument but may also speak to some:
    in a similar discussion one could say that actually there is no object oriented programming, there’s only procedural programming. Does you CPU understand objects?
    Even better, actually there is no software, there’s only differnt hardware states 🙂

    My point is that some terms don’t translate to other layers of abstraction and you should stick the discussion to where it belongs (which in this case is a language, not memory).

    Even the author of this question stated:
    “Note that this question refferes to C# not necessarily .NET and how it handles the data under the hood (obviously it’s all 1’s and 0’s.)”

    Reply
  13. user

    Addressing the semantics, Why overload the word “object” so that it means “reference type” when we already have a perfectly good, unambiguous term for that -> “Reference Type”, and the when, by overloading the word “Object” in this way we create the confusion this thread demonstrates… i.e., the mismatch between the fact that all Types, (including value types), inherit the implementation defined in the Type “System.Object”. Clearly, this is at best unnecessary, and at worst extremely confusing.. Even the fact that the MS documentation is at times confusing on this issue is no excuse to propagate the confusion.

    Much easier, and clearer, is to just define and use the term “object” to mean an instance of ANY type, value or reference, and the phrase “Reference Type” to describe the Types that use pointer variables and have their state stored on the Heap …

    Reply
  14. user

    Considering that the question is referring to Object in a OOP sense, the answers is:

    From a technical point of view the answer is: No

    From a dogmatic point of view the answer is: Yes

    Explanation:

    Technically value types (primitives or structs) are not objects unless in “boxed” form, but because the .Net does seamless conversions of value types to their Object counterpart through the act of boxing/unboxing (creating a class instance that holds the value and is derived from Object) that means value types can be treated as both objects and simple values.

    So value types are dual in nature, they behave as values and as objects. Values in .Net are Objects when they need to be, and they are not objects in the rest of cases.

    The correct answer that takes the technical aspect into consideration is “Everything in .Net is as if it were an Object”.

    The dogmatic answer is “Everything is an Object”.

    Reply
  15. user

    The problem here is that this is really two questions – one question is about inheritance, in which case the answer is “nearly everything”, and the other is about reference type vs value type/memory/boxing, which case the answer is “no”.

    Inheritance:

    In C#, the following is true:

    • All value types, including enums and nullable types, are derived from System.Object.
    • All class, array, and delegate types are derived from System.Object.
    • Interface types are not derived from System.Object. They are all convertible to System.Object, but interfaces only derive from other interface types, and System.Object is not an interface type.
    • No pointer types derive from System.Object, nor are any of them directly convertible to System.Object.
    • “Open” type parameter types are also not derived from System.Object. Type parameter types are not derived from anything; type arguments are constrained to be derived from the effective base class, but they themselves are not “derived” from anything.

    From the MSDN entry for System.Object:

    Supports all classes in the .NET
    Framework class hierarchy and provides
    low-level services to derived classes.
    This is the ultimate base class of all
    classes in the .NET Framework; it is
    the root of the type hierarchy.

    Languages typically do not require a
    class to declare inheritance from
    Object because the inheritance is
    implicit.

    Because all classes in the .NET
    Framework are derived from Object,
    every method defined in the Object
    class is available in all objects in
    the system. Derived classes can and do
    override some of these methods.

    So not every type in C# is derived from System.Object. And even for those types that are, you still need to note the difference between reference types and value types, as they are treated very differently.

    Boxing:

    While value types do inherit from System.Object, they are treated differently in memory from reference types, and the semantics of how they are passed through methods in your code are different as well. Indeed, a value type is not treated as an Object (a reference type), until you explicitly instruct your application to do so by boxing it as a reference type. See more information about boxing in C# here.

    Reply
  16. user

    Based on all books that I read, everything in C# is an object.

    Some are reference other are Value type. Value type object inherit from the class ValueType. They have different behavior but inherently … objects.

    This is the reason why you can store an Int32 in an object variable as well as everything that you can ever create in .NET.

    For more detail… look at the following: http://msdn.microsoft.com/en-us/library/s1ax56ch(VS.71).aspx

    All value types are derived implicitly
    from the Object class.

    Reply
  17. user

    Value types are not objects, they obey different copying semantics, different passing semantics, and must be wrapped in a class (Object) in order to be treated as such.

    Edit: I think the argument is somewhat vague, as you must qualify what you mean by ‘object’. Is an object just something that inherits from Object, or is it something that obeys Object’s use semantics? Or are we talking the most general definition of object, where it is anything that can contain data and operations on that data?

    Reply
  18. user

    You’re confusing an object with a value or reference. Basically, everything is an object. An Int is an object, but it is also a value type. A class instance is an object, but it is also a reference type.

    Methods aren’t objects, nor are properties. The just operate on objects. And yes, pretty much everything inherits from the object class.

    Reply
  19. user

    I thought that value types are NOT objects. They’re stored differently in memory by the CLR – value types are stored on the stack, and objects are stored on the heap. You can cast value types to a reference type to make them act like an object, but the CLR takes the value off of the stack, wraps it in an object, and stores it on the heap. That is what happens when you “box” a variable.

    Reply
  20. user

    In C# (and in OOP in general) we have types (class – reference, struct – value, etc.). These are the definitions. And the “object” is the concrete instance of a given type.

    So, if we read the question literally, yes, everything is an object when instantiated.

    The confusion most probably begins with a bad choosing of the name of the very base class for everything. In .NET this is the Object class.

    Reply
  21. user

    Some people here have a strange notion of what an “object” in object-oriented programming is. In order for something to be an object it does not have to be a reference type or, more generally, follow any formal implementation.

    All that means is that you can operate on it as a first-class citizen in an object-oriented world. Since you can do this on values in C# (thanks to autoboxing), everything is indeed an object. To some extend, this is even true for functions (but arguably not for classes).

    Whether this is relevant in practice is another question but this is a general problem with OOP that I notice once again. Nobody is clear on the definition of OOP (yes, most people agree that it has something to do with polymorphism, inheritance and encapsulation, some throw in “abstraction” for good measure).

    From a usage point of view, every value in C# handles like an object. That said, I like the currently accepted answer. It offers both technically important aspects.

    Notice that in other contexts, e.g. C++, other aspects are stressed since C++ isn’t necessarily object-oriented and furthermore is much more focused on low-level aspects. Therefore, the distinction between objects, POD and builtin primitives makes sometimes sense (then again, sometimes not).

    Reply
  22. user

    Short answer: No.

    The answer hinges on the definition of "object". Different languages have different definitions of what "object"-means, but the authoritative definition for C# is the official C# Language Specification:

    The types of the C# language are divided into two main categories: reference types and value types. (…) Value types differ from reference types in that variables
    of the value types directly contain their data, whereas variables of
    the reference types store references to their data, the latter being
    known as objects.

    So according to the C#, an object is an instance of a reference type. Value type values are therefore not objects. So it is not true that everything is an object in C#.

    However:

    C#’s type
    system is unified such that a value of any type can be treated as an
    object. (…) Values of value types are treated as objects by
    performing boxing and unboxing operations (§9.3.12).

    So a value type can be treated as an object by boxing it (effectively turning into a reference type). But an unboxed value type is not in itself an object.

    The CLR Specification [PDF] uses a definition very similar to C#:

    object: An instance of a reference type. An object has more to it than
    a value. An object is self-typing; its type is explicitly stored in
    its representation. It has an identity that distinguishes it from all
    other objects, and it has slots that store other entities (which can
    be either objects or values). While the contents of its slots can be
    changed, the identity of an object never changes.

    So in the CLR terminology, a value type value is not an object either.

    Reply
  23. user

    While everyone seems to be focusing on the value types vs. reference types debate, we are forgetting one type in C# that is neither reference nor value, it doesn’t derive from object, and it can’t be cast to object: pointers.

    Unlike values and reference types, pointers cannot be cast to object.

    According to the MSDN documentation on C# pointer types,

    Pointer types do not inherit from
    object and no conversions exist
    between pointer types and object.
    Also, boxing and unboxing do not
    support pointers. However, you can
    convert between different pointer
    types and between pointer types and
    integral types.

    Reply
  24. user

    In .NET and C# all is object

    Simply said.

    Even a value type, a struct, an interface and an enum.

    One can not approve, but the point is that everything is object, except pointers/references, and literals from binary files, even CPU optimized primitive types, since it is the OOP Theory as well as the. NET specifications and therefore the facts.

    From the dotnet/csharplang/Type:

    Value types differ from reference types in that variables of the value types directly contain their data, whereas variables of the reference types store references to their data, the latter being known as objects. With reference types, it is possible for two variables to reference the same object, and thus possible for operations on one variable to affect the object referenced by the other variable. With value types, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other.

    C#’s type system is unified such that a value of any type can be treated as an object. Every type in C# directly or indirectly derives from the object class type, and object is the ultimate base class of all types. Values of reference types are treated as objects simply by viewing the values as type object. Values of value types are treated as objects by performing boxing and unboxing operations (Boxing and unboxing).

    That said in fact that value types are object themselves, even if in IL they are manipulated by references, that is called an "unified type system". That said that all is object, but some are used via references to values and others via values. Thus C# is True OOP but not Pure, mainly for optimizations purpose.

    In IL all is a class. All. Except underlying pointers and thus CPU registers, and literals before associated to an object.

    We can check if any variable is type of object and all is always true (Fiddle)

    All strings, numbers, enums, structs, classes and interfaces to objects are objects being type of object. It is what is called being a True OOP Language. But C# is not Pure OOP because of primitive value types, numbers and strings optimizations.

    enum Enumeration { V1, V2 }
    
    struct Structure { string person; }
    
    interface IClass { }
    
    class Class : IClass { }
    
    public static void Main()
    {
      string myStringInstance = "test";
      int myIntegerInstance = 10;
      var myEnumInstance = Enumeration.V1;
      var myListInstance = new List<int>();
      var myStructInstance = new Structure();
      var myClassInstance = new Class();
      var myInterface = (IClass)myClassInstance;
    
      Console.WriteLine(myStringInstance is object);
      Console.WriteLine(myIntegerInstance is object);
      Console.WriteLine(myEnumInstance is object);
      Console.WriteLine(myListInstance is object);
      Console.WriteLine(myStructInstance is object);
      Console.WriteLine(myClassInstance is object);
      Console.WriteLine(myInterface is object);
      Console.ReadKey();
    }
    
    > True
    > True
    > True
    > True
    > True
    > True
    > True
    

    Now let’s see the differences between a class and a struct at the IL low-level generated code, before converted to the target machine code:

    struct Struct { public int Value; }
    
    class Class { public int Value; }
    
    public static void Main()
    {
      var myClass = new Class();
      myClass.Value = 10;
      Console.WriteLine(myClass.Value);
    
      var myStruct = new Struct();
      myStruct.Value = 20;
      Console.WriteLine(myStruct.Value);
    }
    

    This is what it looks like:

    .maxstack 2
    .entrypoint
    .locals init (
      [0] class Program/Class myClass,
      [1] valuetype Program/Struct myStruct
    )
    
    // Class @class = new Class();
    IL_0001: newobj instance void Program/Class::.ctor()
    IL_0006: stloc.0
    
    // @class.Value = 10;
    IL_0007: ldloc.0
    IL_0008: ldc.i4.s 10
    IL_000a: stfld int32 Program/Class::Value
    
    // Console.WriteLine(@class.Value);
    IL_000f: ldloc.0
    IL_0010: ldfld int32 Program/Class::Value
    IL_0015: call void [mscorlib]System.Console::WriteLine(int32)
    
    IL_001b: ldloca.s 1
    
    // Struct @struct = default(Struct);
    IL_001d: initobj Program/Struct
    
    // @struct.Value = 20;
    IL_0023: ldloca.s 1
    IL_0025: ldc.i4.s 20
    IL_0027: stfld int32 Program/Struct::Value
    
    // Console.WriteLine(@struct.Value);
    IL_002c: ldloc.1
    IL_002d: ldfld int32 Program/Struct::Value
    IL_0032: call void [mscorlib]System.Console::WriteLine(int32)
    

    So let’s say that here, at this level, there is no real difference between an object instance of a class and an object instance of a structure because the compiler does the job of treating them according to their gender. And so that they have the behavior of reference type or value type. Otherwise there, in assembly, there is not really any difference any more except when it is necessary but all is pointers. Almost everything, way of speaking, towards memory cases essentially via CPU registers.

    newobj

    initobj

    As we can see, class or struct, it is an object, handled in two ways, but in the same way, as in a two-lane road.

    About objects and instances

    Terms object and instance can be considered synonyms, but they are not really synonymous from the point of view of scrupulous terminology. The object is the concrete materialization of the type (concept or idea) in the real world (the virtual compouter world, thus the physical memory). The instance is rather the mental existence of this object, in the human mind, therefore in the software code. So these words are "synonyms", but:

    An object (existence) is an instance (presence) of a type (thought).

    In C# .NET managed code, there is no pointer. Pointers are not objects. Pointers are the address of objects stored in memory. In C# we use references that are hiddens pointers to forget to manage them. A pointer is just a memory cell address like in a town. We could say that they are objects, but not in the sense of objects in OOP: these pointers, via the references, allow us to create, manipulate and destroy the objects that we use to build applications that runs on a machine to take data, process data and output data and/or control another device.

    In OOP, all is object: en.wikipedia.org/wiki/Object_(computer_science).

    An object is an instance of a type.

    The words object and instance can be considered synonyms, but they are not really synonymous from the point of view of scrupulous terminology. The object is the concrete materialization of the type or concept or idea in the real world, in the physical memory. The instance is the mental existence of this object, in the human mind, in the software code. So these words are "synonyms", but an object (existence) is an instance (presence) of a type (thought).

    Words type and class or struct are not synonyms. One can consider object and instance synonyms, but not these words: class, struct, enum or interface are types. For example, a chair and a table are furniture, but chair and furniture are not synonyms. One can imagine that the word type is the "root class" (parent concept) and words class or struct… are "child classes" (child concepts), in terms of linguistic. So they are not synonyms: there is a level of abstraction that make the difference, like in a tree of terminology.

    An instance (the data in the mind to be manipulated by the code) of a struct type (the static definition) is an object (in the computer memory).

    One can find answers to fundamental questions by studying the basics up to Intel. To understand the motor of the car we need to open the hood, not to dissect the steering wheel or the tires nor the armchairs. To understand the underlying of virtual .NET we need to study the CPU itself, and that, is fascinating, else we can easily lost time and misunderstood things with confusion and non-sense – same for C# based on OOP Theory.

    Sometimes source of knowledge the web as well as in books may be partial or misleading due to errors, oversight, misunderstanding, confusion, or ignorance. Hence the importance of starting with few sources of few experts, like one or two reliable and reputable origin, from the basics, and books or professional courses are the best, rather than scattering. Once mastered, we can open the field and domains with more and don’t be scared about discrepancies or contradictions.

    About boxing and unboxing

    About boxing/unboxing: a variable = an object in OOP, that is an instance of a struct or a class, can be boxed to object and unboxed from object : C# Guide. Essentially, unboxed, a value type is an object that doesn’t look like an object (it is "shrunken") in order to be optimized for processing by our silicon microprocessors, so there are a lot of speed and memory improvements in the IL code and therefore in the targeted machine code. Boxed, this value type is a full object as such, put in an entire box, and being no longer cheap. A boxed value type is used as the full object without optimizations and sepcial behaviors: it is now a reference we manipulate to access the embedded value in the "original" class.

    An unboxed value is the value itself ie the memory cell itself if an integer, in the RAM memory and/or CPU register being x32 or nowadays x64 (one cell here). A boxed value is a reference to a full object instance embedding this value (many cells). The unboxed is manipulated without using "all the full" but the boxed use that. Thus this last is slower and bigger. But an apple remains an apple. For example, if a method requires an object instance being of type Object, we must box an integer, because it only accepts the root type of all.

    That means that boxing take an optimized ie a not-pure object like an integer value (a one memory cell) to create a full object Int32. Thus this one-cell memory in the stack in assigned to the int property of the new Int32 object in the heap.

    Isn’t boxing & unboxing a special case of direct casting?

    We call that boxing and unboxing because once boxed to object type, we can unbox without having a compiler type conversion error as any type mismatch will be raised at runtime.

    From OpCodes.Box Field:

    Converts a value type to an object reference (type O).

    The stack transitional behavior, in sequential order, is:

    1. A value type is pushed onto the stack.
    2. The value type is popped from the stack; the box operation is performed.
    3. An object reference to the resulting "boxed" value type is pushed onto the stack.

    A value type has two separate representations within the Common
    Language Infrastructure (CLI):

    • A ‘raw’ form used when a value type is embedded within another object or on the stack.
    • A ‘boxed’ form, where the data in the value type is wrapped (boxed) into an object so it can exist as an independent entity.

    The box instruction converts the ‘raw’ (unboxed) value type into an
    object reference (type O). This is accomplished by creating a new
    object and copying the data from the value type into the newly
    allocated object. valTypeToken is a metadata token indicating the type
    of the value type on the stack.

    In terms of machine code material architecture dependant as with an Intel-type microprocessor, it is nothing more than using a memory pointer after performing all the specified processings.

    Here is another sample:

    int valueInt = 10;
    double valueDouble = (double)valueInt;
    object instance = (object)valueInt;
    int value = (int)instance;
    

    IL generated code is:

    .method private hidebysig static 
        void Test () cil managed 
    {
        .maxstack 1
        .locals init (
            [0] int32 valueInt,
            [1] float64 valueDouble,
            [2] object 'instance',
            [3] int32 'value'
        )
    
        // int num = 10;
        IL_0001: ldc.i4.s 10
        IL_0003: stloc.0
    
        // double num2 = num;
        IL_0004: ldloc.0
        IL_0005: conv.r8
        IL_0006: stloc.1
    
        // object obj = num;
        IL_0007: ldloc.0
        IL_0008: box [mscorlib]System.Int32
        IL_000d: stloc.2
    
        // int num3 = (int)obj;
        IL_000e: ldloc.2
        IL_000f: unbox.any [mscorlib]System.Int32
        IL_0014: stloc.3
    
        IL_0010: ret
    }
    

    From OpCodes.Unbox Field:

    Converts the boxed representation of a value type to its unboxed form.

    The stack transitional behavior, in sequential order, is:

    1. An object reference is pushed onto the stack.
    2. The object reference is popped from the stack and unboxed to a value type pointer.
    3. The value type pointer is pushed onto the stack.

    A value type has two separate representations within the Common
    Language Infrastructure (CLI):

    • A ‘raw’ form used when a value type is embedded within another object.
    • A ‘boxed’ form, where the data in the value type is wrapped (boxed) into an object so it can exist as an independent entity.

    The unbox instruction converts the object reference (type O), the
    boxed representation of a value type, to a value type pointer (a
    managed pointer, type &), its unboxed form. The supplied value type
    (valType) is a metadata token indicating the type of value type
    contained within the boxed object.

    Unlike Box, which is required to make a copy of a value type for use
    in the object, unbox is not required to copy the value type from the
    object. Typically it simply computes the address of the value type
    that is already present inside of the boxed object.

    Since classes and structures are in fact the same thing, of course managed differently, but being only references and "hidden-references" (hidden and "hidden-hidden" memory pointers to forget to manage them as well as accessing and using, and to delegate this to the CLR), boxing and unbowing of value-types and non-value-types is essentially the same at this low level of operation, so the IL code does not differentiate between the two.

    About OOP

    All that: .NET, C#, OOP, casting, boxing, unboxing… is just high-level language sugar over machine code to allow humans to be able to do things better and simpler but more complex and more powerful in less time.

    We must keep in mind that object (tree) can mean two things : object instance in term of OOP (plant), and C# root for all classes/structs/enums object (graph). But that’s in reality the same thing because all is object at the highest level of abstraction. Objects instance of a type being a reference type or a value type, are objects, in the two cases. Its upper typeof is object : a struct, a class and a enum is type of object. Always. We have checked that by code and see what is the truth.

    In C# .NET OOP, all objects are type of Object class, and any struct is in fact a class, a special class: for IL it is a sub-class of Object. Also any interface is a class, a special class: for IL it is a sub-class of Object. This said in a simplified way.

    By writting Object we ensure that we talk about the root class type that is the ancestor of all .NET types (classes, structs, enums, numbers). When we talk about objects we refer to instance of type being of this System.Object root class. Also objects types can be references or value type: that is how the compiler manage special cases and behaviors and optimizations… Thus this comment is misleading. Forget it.

    In OOP, everything is an object. This is the theory. Even value types are objects, specials compared to other classes. Everything is explained in duplicates. It is impossible to understand in such fundamental low-level objects nature, memory as well as coding, without learning this theory and how the motherboard works. Impossible without confusion and asking the same questions eternally, in my opinion. It is like trying to understand what are stars without studying atoms.

    In OOP, everything is an object. We manipulate objects that have properties or attributes and operations or methods. Even in non-OOP like structured and functionnal. In the end everything is an object whatever its specialized type. The smallest object, the computer atom, is the memory cell and the bit box. Over 0’s and 1’s of this silicon microprocessor era, the smallest object a computer can store is defined by its register size: 8, 16, 32, 64… bits. This is the basic object: byte word dword qword… All is matter.

    An object (an object is an instance of a class) of type ValueType is of type a class that inherits from object C# class. Thus all is class is C#, even interfaces (in IL).

    What is it if not an object? In life and in the universe, everything is object, movement, construction, interaction, evolution, destruction… Any event relating to a phenomenon requires a physical support, and this support is called object, intsance of the phenomenon (concepts and laws). Nothing exists without matter. Those who say otherwise are just liars. So if a value-type, integral/struct/str, that is at the top level a class aka an object, otherwise what is it? A spirit ? But spirit is matter: the object, alive (made and moving) as well as dead (des not move and is garbadged)

    It is the OOP Theory that does that. It is those who developed this theory who stated that. I just agree. It’s the same with the Cell Theory which states that all life comes from the cell (DNA/RNA/Organites) and nothing else than the laws like gravity.

    In OOP everything is object = Object even in C# where all is an object of type a class even integral types, structs, numbers and enums as well as strings. Nothing else. It does not matter at this level of abstraction what nuances we bring to the types of objects.

    In contrast to that, at low-level, in virtual IL assembly and in CPU-ASM machine code, numbers are simple bytes values in the CPU internal registers, thus they are not OOP objects… But such consideration without knowing what about we call is confusing because C# manipulates objects, all is object, even once compiler optimizations are done unlike in Haskell or Smalltalk, if I remember and don’t say an error about these true and pure OOP languages.

    DotNet is not pure OOP. For example, when we change the value of an integer, the IL code changes the content of the cell at the address reserved for this value. It uses the same address. It just do what will become a wimple MOV addr, 10. It does not create a copy using another cell or object by putting to trash the old cell or object.

    Concerning literals, they can’t be considered as objects because they are hard-coded in the EXE binary. The running machine code loads a literal value (or its address to be associated to the new created object) from the data-segment in a register and/or in a variable reserved cell address when we write int a = 10; : the 10 is in the EXE data segment loaded at startup in memory. That, is not an object in term of OOP: it just some raw contiguous bytes (integer, string, arrays of integral types): literals are not variables and nothing about variables applies to literals which are pure raw data without any abstraction or encapsulation.

    .maxstack 1
    .locals init ( [0] string str )
    
    // string str = "This a literal test string for Stack Overflow!";
    IL_0001: ldstr "Test"
    IL_0006: stloc.0
    
    // Console.WriteLine(str);
    IL_0007: ldloc.0
    IL_0008: call void [mscorlib]System.Console::WriteLine(string)
    

    This IL instruction in the code-segment loads the "This is a literal test…" raw bytes stored in the binary EXE file in a str object instance created and being of type string and referenced by the memory address pointer in the stack at position "0", and then this local reference is passed to the Console method.

    Here is a compiler generated EXE dump, wagons of raw bytes stored in the data segment loaded when the process started and used to create the new string instance like using a scanner to create an image file:

    enter image description here

    The raw bytes of a file are not objects as such as considered in OOP: they become objects when instances are created once the application is started, to load pre-defined data or to handle files. They are just raw bytes before the program is running, not objects, not yet.

    I therefore encourage you to study the foundations of this OOP theory: abstraction, encapsulation, inheritance and polymorphism.

    As well as the foundations of computers based on silicium microprocessors on a motherboard having some memory.

    And if you ask me what is the ancestor of object… SO 🙂

    The previous and following links are for information and demonstration only. Some are trustworthy, others may contain errors, contradictions or ignorance on the subject, and also opinions, true or false, sometimes difficult to bring into real reality.

    Also keep in mind that I could have misconstrued and made inaccuracies or even imperfections, especially since I’m not so good in English, not my mother tongue and I have no oral skills, and my memories in Assembly are old and in old computers before the x64 era, and that I did not too much invested in the IL/CLR study, but what I explained, basically, it’s like that, pretty much.

    OOP, abstraction, encapsulation and more

    Looking for a pure object oriented language

    Difference between pure object oriented and object oriented language

    What is a "pure object oriented language" in the context of DCI?

    What Are OOP Concepts?

    What is abstraction in C#?

    How to choose between public, private and protected access modifier?

    What is polymorphism?

    What is the difference between an interface and a class?

    What's the difference between struct and class in .NET?

    Why methods return just one kind of parameter in normal conditions?

    Literals and immutables

    How are integer literals stored?

    Why are C# number types immutable?

    Mutable And Immutable Class In C#

    Understanding String Immutability in C#

    Immutable objects in C#

    What is the difference between a mutable and immutable string in C#?

    In C# , Are Value types mutable or immutable ?

    What are mutable Classes. How can we create a mutable and immutable class in C#

    Boxing and unboxing

    Why do we need boxing and unboxing in C#?

    What is the real use of boxing and unboxing?

    Boxing and Unboxing in C#

    C# | Boxing And Unboxing

    A look at the internals of ‘boxing’ in the CLR

    How does boxing and unboxing work at the lowest level

    Memory, heap and stack

    c# – What happens in memory when creating objects?

    Meanings of declaring, instantiating, initializing and assigning an object

    How are integer literals stored?

    C# How to store a string

    Does using "new" on a struct allocate it on the heap or stack?

    Are these objects's references on the Stack or on the Heap?

    Fields of class, are they stored in the stack or heap?

    Memory Allocation for Variable Declared in Class

    How does a struct instance's virtual method get located using its type object in heap?

    How does the heap and stack work for instances and members of struct in C#?

    Where does a value type-variable – which is returned by ref – live? Stack or heap?

    Memory allocation: Stack vs Heap?

    Static class memory allocation where it is stored C#

    How would the memory look like for this object?

    Operating System, CPU and IL

    Operating System Tutorial

    Operating System Concepts Book

    Intel® 64 and IA-32 Architectures Software Developer Manuals

    .NET via CLR

    MSIL Programming 1

    MSIL Programming 2

    MSIL Programming

    MSIL in Depth

    Reply
  25. user

    One of the reasons why there are so many different answers is that the question is very imprecise. What does "everything" mean? Does it really mean every C# language element? Then the answer is clearly "no": Operators are not objects, the "using" keyword is not an object, comments are not objects, etc.

    But if this was not meant, what was then meant? Maybe "everything apart from those things that are obviously not classes"? This is obviously not helpful as different people have different opinions on what is "obvious". Nevertheless, most answers seem to follow along this line of opinionated interpretation.

    Another source of confusion is around the term "object". What is an object? There is no unique universal definition of this term and different people seem to use it in a different way. The only formal definition in the C# language is the definition of the System.Object type and which other types derive from it and which not. This documentation is readily available and more can’t be said about it.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *