37 votes

Quelle est la différence entre sizeof (T) et Unsafe.SizeOf <T> ()?

Tout d'abord, un petit avertissement avant de le libellé de la question:

Je sais qu'il y a beaucoup de choses de fermé/dupliquer des questions quant à la différence entre le sizeof de l'opérateur et de l' Marshal.SizeOf<T> méthode, et je ne comprends la différence entre les deux. Ici je parle de l' SizeOf<T> méthode dans le nouveau Unsafe classe

Donc, je ne suis pas sûr de comprendre la différence réelle entre ces deux opérations, et si il y a une différence donnée lors de l'utilisation de la méthode sur une struct/classe en particulier.

L' sizeof - opérateur prend un nom de Type et retourne le nombre de géré octets qu'il est censé prendre lors de alloués (ie. un Int32 sera de retour le 4, par exemple).

L' Unsafe.SizeOf<T> méthode sur l'autre main, est mis en œuvre dans IL comme toutes les autres méthodes dans l' Unsafe classe, et en regardant le code, voici ce que ça donne:

.method public hidebysig static int32 SizeOf<T>() cil managed aggressiveinlining
{
    .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 )
    .maxstack 1
    sizeof !!T
    ret
}

Maintenant, si je ne me trompe pas, le code est juste appelant sizeof !!T qui est le même que sizeof(T) (l'appel de la sizeof de l'opérateur avec le nom du type T), donc ne pas les deux d'entre eux exactement l'équivalent?

Aussi, je vois de la méthode est également l'allocation d'un objet inutile (l' NonVersionableAttribute) dans la première ligne, afin de ne pas causer une petite quantité de mémoire pouvant être allouées sur la pile ainsi?

Ma question est:

Est-il sûr de dire que les deux méthodes sont parfaitement équivalents et que, par conséquent, il est juste préférable d'utiliser le classique sizeof - opérateur, comme aussi d'éviter l'affectation de l'attribut dans l' SizeOf<T> méthode? Était-ce SizeOf<T> ajout de la méthode à l' Unsafe classe juste pour la commodité à ce point?

29voto

Evk Points 17804

Bien que cette méthode, en effet, utilise juste sizeof instruction IL - il y a une différence avec les régulières sizeof de l'opérateur, parce que cet opérateur ne peut pas être appliquée à des types arbitraires:

Utilisé pour obtenir la taille, en octets, pour un non géré type. Non managé les types incluent les types intégrés qui sont répertoriés dans le tableau suit, et également les éléments suivants:

Les types Enum

Types de pointeur

Défini par l'utilisateur des structures qui ne contiennent pas de les champs ou propriétés qui sont des types référence

Si vous essayez d'écrire analogique de Unsafe.SizeOf - cela ne fonctionnera pas:

public static int SizeOf<T>()
{
    // nope, will not compile
    return sizeof(T);
}

Donc, Unsafe.SizeOf ascenseurs restrictions d' sizeof de l'opérateur et de vous permettre d'utiliser, IL sizeof instruction avec des types arbitraires (y compris les types de référence pour qui il sera de retour de la taille de référence).

Comme pour l'attribut construire vous voir dans IL - qui ne signifie pas l'attribut sera instancié pour chaque appel, c'est l'IL de la syntaxe pour l'association d'attributs avec les différents membres (méthode dans ce cas).

Exemples:

public struct Test {
    public int Int1;
}

static void Main() {
    // works
    var s1 = Unsafe.SizeOf<Test>();
    // doesn't work, need to mark method with "unsafe"
    var s2 = sizeof(Test);            
}

Un autre exemple:

public struct Test {
    public int Int1;
    public string String1;
}


static unsafe void Main() {
    // works, return 16 in 64bit process - 4 for int, 4 for padding, because
    // alignment of the type is the size of its largest element, which is 8
    // and 8 for string
    var s1 = Unsafe.SizeOf<Test>();
    // doesn't work even with unsafe, 
    // cannot take size of variable of managed type "Test"
    // because Test contains field of reference type (string)
    var s2 = sizeof(Test);                        
} 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X