web-dev-qa-db-fra.com

Est-ce que tout dans .NET est un objet?

Aidez-nous à régler la controverse liée à "Presque", tout est un objet ( une réponse à la question Stack Overflow En tant que novice, dois-je me méfier avant d'apprendre le C #? ). Je pensais que c'était le cas, car tout dans Visual Studio apparaît au moins comme une structure. S'il vous plaît poster une référence, afin qu'il ne devienne pas "jackass moderne" ( This American Life ).

Notez que cette question fait référence à C #, pas nécessairement .NET, et à la façon dont elle traite les données sous le capot (évidemment, ce sont tous les 1 et les 0).

Voici les commentaires à "tout est un objet":

  • Eh non, ce n'est pas. - Binary Worrier
  • J'aimerais un exemple ... - scotty2012
  • tout n'est-il pas dérivé du type de base Object? - rizzle
  • La plupart des choses sont des objets ... - Omar Kooheji
  • Les types de valeur, ints, doubles, références d'objet (pas les objets eux-mêmes), etc. ne sont pas des objets. Ils peuvent être "encadrés" pour ressembler à des objets (par exemple, i.ToString ()), mais ce sont en réalité des types primitifs. Changez l'entrée en "presque tout est un objet" et je supprimerai le vote négatif - Binary Worrier
  • J'apprécie la clarification. Je pense que le niveau le plus bas avec lequel vous pouvez interagir, disons un int, en C #, est une structure qui n'est pas un objet? - http://msdn.Microsoft.com/en-us/library/ms173109.aspx - rizzle
  • Int32 n'hérite-t-il pas de ValueType qui hérite de Object? Si c'est le cas, malgré le comportement, un int est un objet. - Chris Farmer
  • Non, le type boxed pour int hérite de ValueType, qui hérite de Object. Ce ne sont pas des objets au sens traditionnel car a) un int n'est pas une référence à un int, IT IS l'int. b) les déchets ne sont pas ramassés. Si vous déclarez un Int32, alors il s'agit de 4 octets sur la pile, fin de l'histoire - Binary Worrier

Définition de l'objet: "Objet" en tant qu'héritier de la classe System.Object et "objet" en tant qu'instance d'un type contre "objet" en tant que type de référence. "

48
rizzle

Le problème ici est qu’il s’agit en réalité de deux questions - une question sur l’héritage, auquel cas la réponse est "presque tout", et l’autre sur le type référence/type valeur/mémoire/boxe, auquel cas la réponse est "non ".

Héritage:

En C #, ce qui suit est vrai:

  • Tous les types de valeur, y compris les types enum et nullable, sont dérivés de System.Object
  • Tous les types de classe, de tableau et de délégué sont dérivés de System.Object.
  • Les types d'interface ne sont pas dérivés de System.Object. Ils sont tous convertibles en System.Object, mais les interfaces ne dérivent que d'autres types d'interface, et System.Object n'est pas un type d'interface. 
  • Aucun type de pointeur ne provient de System.Object, et aucun d’eux n’est directement convertible en System.Object.
  • Les types de paramètre de type "ouvert" ne sont pas non plus dérivés de System.Object. Les types de paramètres de type ne sont dérivés de rien; Les arguments de type doivent obligatoirement être dérivés de la classe de base effective, mais ils ne sont eux-mêmes "dérivés" de rien.

De l'entrée MSDN pour System.Object :

Prend en charge toutes les classes de la hiérarchie de classes .NET Framework et fournit Des services de bas niveau aux classes dérivées. Il s'agit de la classe de base ultime de toutes les classes Dans le .NET Framework; c'est la racine de la hiérarchie des types.

Les langues n'ont généralement pas besoin d'une classe Pour déclarer l'héritage d'un objet , Car l'héritage est Implicite.

Comme toutes les classes du .NET Framework sont dérivées d'Object, Chaque méthode définie dans la classe Object Est disponible dans tous les objets du système. Les classes dérivées peuvent et font Remplacer certaines de ces méthodes.

Donc, tous les types en C # ne sont pas dérivés de System.Object. Et même pour les types qui le sont, vous devez toujours noter la différence entre les types reference et les types value , car ils sont traités de manière très différente.

Boxe:

Bien que les types de valeur fassent hériter de System.Object, ils sont traités différemment en mémoire par rapport aux types de référence, et la sémantique de la façon dont ils sont transmis par les méthodes dans votre code est également différente. En effet, un type de valeur n'est pas traité en tant qu'objet (type de référence), jusqu'à ce que vous en donniez explicitement la consigne à votre application en la boxant en tant que type de référence. Voir plus d’informations sur la boxe en C # ici .

79
Daniel Schaffer

Un peu tard pour la fête, mais j'ai trouvé cela dans un résultat de recherche sur SO et j'ai pensé que le lien ci-dessous aiderait les générations futures:

Eric Lippert en discute de manière très approfondie , avec une affirmation (qualifiée) bien meilleure:

La façon de corriger ce mythe est simplement de remplacer "dérive de" par "est convertible en" et d'ignorer les types de pointeur: chaque type de non-pointeur dans C # est convertible en objet.

En résumé, si vous détestez lire des explications bien illustrées de personnes écrivant des langages de programmation, c’est que (pointeurs mis à part), des éléments tels que Interface ou des déclarations de type de paramètre générique ("T") ne sont pas des objets, mais sont garantis. traitables en tant qu’objets au moment de l’exécution, car ils ont une instance définie, ce sera un objet. Les autres types (Type, Enum, Delegate, classes, etc.) sont tous des objets. Y compris les types de valeur, qui peuvent être encadrés pour objecter comme d'autres réponses l'ont discuté.

29
Matt Enright

Certaines personnes ici ont une notion étrange de ce qu'est un «objet» dans la programmation orientée objet. Pour que quelque chose soit un objet, il pas doit être un type de référence ou, plus généralement, suivre toute implémentation formelle.

Tout ce que cela signifie, c'est que vous pouvez l'utiliser en tant que citoyen de premier plan dans un monde orienté objet. Puisque vous pouvez faites cela sur les valeurs en C # (grâce à la substitution automatique), tout est en effet un objet. Dans une certaine mesure, cela est même vrai pour les fonctions (mais sans doute pas pour les classes).

La question de savoir si cela est pertinent en pratique est une autre question, mais il s'agit d'un problème général avec OOP que je remarque à nouveau. Personne n'est clair sur la définition de OOP (oui, la plupart des gens s'accordent pour dire que cela a à voir avec le polymorphisme, l'héritage et l'encapsulation, certains jettent de "l'abstraction" pour faire bonne mesure).

D'un point de vue de l'utilisation, chaque valeur de C # se comporte comme un objet. Cela dit, j'aime bien la réponse actuellement acceptée. Il offre les deux aspects techniquement importants.

Notez que dans d'autres contextes, par exemple C++, d'autres aspects sont soulignés, car C++ n'est pas nécessairement orienté objet, mais est beaucoup plus concentré sur les aspects de bas niveau. Par conséquent, la distinction entre objets, POD et primitives intégrées est parfois logique (encore une fois, parfois non).

16
Konrad Rudolph

Ils sont tous traités comme des objets , mais ce ne sont pas tous des objets. La confusion entre avec Autoboxing. 

Voir ceci pour plus d'informations: http://en.wikipedia.org/wiki/Object_type

L'abstraction déroute apparemment les gens.

7
GEOCHET

Vous confondez un objet avec une valeur ou une référence. Fondamentalement, tout est un objet. Un Int est un objet, mais c'est aussi un type de valeur. Une instance de classe est un objet, mais c'est aussi un type de référence.

Les méthodes ne sont ni des objets ni des propriétés. Les justes opèrent sur des objets. Et oui, pratiquement tout hérite de la classe d'objets.

6
BBetances

Je pensais que les types de valeur ne sont PAS des objets. Ils sont stockés différemment en mémoire par le CLR - les types de valeur sont stockés dans la pile et les objets sont stockés dans le segment de mémoire. Vous pouvez transtyper les types de valeur en types de référence pour qu'ils agissent comme un objet, mais le CLR extrait la valeur de la pile, l'encapsule dans un objet et la stocke dans le segment de mémoire. C'est ce qui arrive quand vous "boxez" une variable. 

6
Rich

En C # (et en OOP en général), nous avons des types (class-reference, struct-value, etc.). Ce sont les définitions. Et "l'objet" est l'instance concrète d'un type donné.

Donc, si nous lisons littéralement la question, oui, tout est un objet lorsqu’il est instancié.

La confusion commence probablement avec un mauvais choix du nom de la classe de base pour tout. Dans .NET c'est la classe Object.

5
Sunny Milenov

De: Types de valeur (référence C #) - MSDN 3.5

Tous les types de valeur sont dérivés implicitement Du System.ValueType.

De: Type de valeur Classe - MSDN 3.5

ValueType remplace les méthodes virtuelles À partir d'Object avec davantage d'implémentations [] appropriées pour les types de valeur .

De: Enum Class - MSDN 3.5

Cette classe hérite de ValueType

La hiérarchie des héritages est la suivante:

  • System.Object
    • System.ValueType
      • System.Enum

      Conclusion: Tout est objet

3
Gavin Miller

Basé sur tous les livres que j'ai lus, tout en C # est un objet.

Certains sont des références, d'autres sont des types de valeur. Le type d'objet de valeur hérite de la classe ValueType . Ils ont un comportement différent mais intrinsèquement ... des objets.

C'est la raison pour laquelle vous pouvez stocker un Int32 dans une variable d'objet, ainsi que tout ce que vous pouvez créer dans .NET.

Pour plus de détails, consultez les éléments suivants: http://msdn.Microsoft.com/en-us/library/s1ax56ch(VS.71).aspx

Tous les types de valeur sont dérivés implicitement De la classe Object.

3
Maxime Rouiller

Alors que tout le monde semble se concentrer sur le débat types de valeur vs types de référence, nous oublions un type en C # qui n'est ni référence ni valeur, il ne dérive pas d'objet et ne peut pas être converti en objet: des pointeurs.

Contrairement aux valeurs et aux types de référence, les pointeurs ne peuvent pas être convertis en objet.

Selon la documentation MSDN sur les types de pointeurs C # ,

Les types de pointeurs n'héritent pas de l'objet Et il n'existe aucune conversion Entre les types de pointeurs et les objets. En outre, boxing et unboxing ne prennent pas en charge les pointeurs. Cependant, vous pouvez Convertir entre différents types de pointeur Et entre types de pointeur et types de Intégrales.

2

Cela dépend de ce que vous entendez par "tout" et par "est un objet". Si vous définissez ces deux termes, la réponse est simple :-)

Par exemple, dans certaines langues, un if-block est un objet qui peut être transmis sous forme de valeur, affecté à une variable, etc. Ce n'est pas le cas en C #, il est donc évident que tout n'est pas un objet en C #.

2
JacquesB

Les types de valeur ne sont pas des objets, ils obéissent à une sémantique de copie et à une sémantique différentes et doivent être encapsulés dans une classe (Object) pour être traités en tant que tels.

Edit: Je pense que l'argument est quelque peu vague, car vous devez nuancer ce que vous entendez par «objet». Un objet est-il juste quelque chose qui hérite de Object ou est-ce quelque chose qui obéit à la sémantique d'utilisation de Object? Ou parlons-nous de la définition la plus générale d'objet, où tout ce qui peut contenir des données et des opérations sur ces données?

0
Ron Warholic

Le nombre 2 n'est pas un objet.

0
Joe Phillips

Considérant que la question fait référence à Object dans un sens OOP, la réponse est:

D'un point de vue technique , la réponse est: Non

D'un point de vue dogmatique , la réponse est: Oui

Explication:

Techniquement, les types de valeur (primitives ou structures) ne sont des objets que sous forme "encadrée", mais parce que .Net effectue des conversions transparentes des types de valeur en contrepartie Object via l'acte de boxing/unboxing (création d'une instance de classe contenant la valeur et est dérivé de Object), ce qui signifie que les types de valeur peuvent être traités à la fois comme des objets et comme des valeurs simples.

Les types de valeur sont donc de nature dual, ils se comportent comme valeurs et comme objets . Les valeurs en .Net sont des objets quand elles doivent l'être et ne sont pas des objets dans le reste des cas.

La réponse correcte qui prend en compte l'aspect technique est "Tout dans .Net est comme s'il s'agissait de un objet".

La réponse dogmatique est "Tout est un objet".

0
Pop Catalin

C'est une discussion sur deux mondes: le langage et la mémoire.

Pour moi, le langage est comme une couche d'abstraction et le terme objet appartient à ce niveau d'abstraction. Je ne vois pas l'utilité de parler d'objets en termes d'organisation de la mémoire et si vous utilisez le terme "objet" quand vous parlez de mémoire, vous empruntez ce terme à une couche d'abstraction différente. Ainsi, vous ne devriez pas oublier d'où il vient.

Si nous parlons de C #, je ne comprends pas pourquoi quelqu'un utiliserait l'organisation de la mémoire comme argument. Bien sûr, si je répondais à cette question à quelqu'un, je dirais "Oui, en C #, tout est un objet, mais vous devez également savoir que sous le capot, cela peut fonctionner différemment selon que ..."

Cela peut constituer un argument intéressant, mais également: Dans une discussion similaire, on pourrait dire qu’il n’existe pas de programmation orientée objet, mais uniquement de programmation procédurale. La CPU comprend-elle les objets? Mieux encore, il n’existe aucun logiciel, il n’ya que des états matériels différents :)

Mon point est que certains termes ne se traduisent pas en d’autres couches d’abstraction et que vous devriez coller la discussion à l’endroit où elle appartient (qui dans ce cas est une langue, pas de mémoire).

Même l'auteur de cette question a déclaré: "Notez que cette question s'adresse à C #, pas nécessairement .NET et à la façon dont elle traite les données sous le capot (évidemment, il s'agit uniquement de 1 et de 0."

0
Piotr Owsiak

C # a été appelé système de type unifié. Cela signifie que tout peut être vu comme un objet. Cependant, il existe deux types différents: les types de valeur et les types de référence. Les types de valeur peuvent être considérés comme un objet via le mécanisme de boxe. Cela signifie qu'un objet est créé représentant la valeur du type de valeur en question. 

0
Brian Rasmussen

En ce qui concerne la sémantique, pourquoi surcharger le mot "objet" de sorte qu'il signifie "type de référence" alors que nous avons déjà un terme parfaitement correct et sans ambiguïté -> "Type de référence", et quand, en surchargeant le "objet" dans De cette façon, nous créons la confusion que ce thread démontre ... c'est-à-dire le décalage qui existe entre le fait que tous les types (y compris les types de valeur) héritent de l'implémentation définie dans le type "System.Object". De toute évidence, cela est au mieux inutile, et au pire extrêmement déroutant. Même le fait que la documentation de l’EM soit parfois déroutante sur cette question n’est pas une excuse pour propager la confusion.

Il est beaucoup plus facile et clair de simplement définir et utiliser le terme "objet" pour désigner une instance de TOUT type, valeur ou référence, et la phrase "Type de référence" pour décrire les types qui utilisent des variables de pointeur et dont l'état est stocké. le tas ... 

0
Charles Bretana