2

On MSDN I read this:

AVOID defining a struct unless the type has all of the following characteristics: [...] It has an instance size under 16 bytes.

Based on this post by Jon Skeet I conclude that a strings memory-usage is at least 20bytes.

So I wonder if creating a struct with a string-member is considered good thing or not. I am aware that the mentioned article on MSDN states "avoid" instead of "you must not". Having said this I am not sure why this limit of 16bytes is proposed at all.

Community
  • 1
  • 1
MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111

1 Answers1

4

The string data does not live inside of the struct. The struct only stores an 8-byte object reference (if on 64 bit).

This limit is meant to be a simple performance heuristic. Big structs are expensive to copy. If copying is not a problem in your case you can disregard that advice completely.

For example, if you are mainly using big arrays of such structs and accessing the array elements by reference there is no copying. When you say bigArray[i].x++ this directly modifies x in place.


Subjective note:

I'm also not a fan of sweeping generalizations such as the one you quoted. I find that understanding performance characteristics in more details allows you to completely do away with such simple rules. But that's not the point of this question.

usr
  • 168,620
  • 35
  • 240
  • 369
  • 2
    The full quote ends with *In all other cases, you should define your types as classes.*, so it is a *should*, so a suggestion more than an imperative. So a generalization is probably ok. – xanatos Mar 08 '16 at 12:29
  • @xanatos As you can see ony my last paragraph I also mentioned this, that´s why I even wondered for what reason they´ve added this limitation. – MakePeaceGreatAgain Mar 08 '16 at 12:30
  • I think `bigArray[i].x++` won´t even compile for structs. – MakePeaceGreatAgain Mar 08 '16 at 12:32
  • @HimBromBeere Arrays have special handling... It works: https://ideone.com/sX2CEF (both for `x` field and `x` property) – xanatos Mar 08 '16 at 12:36
  • @HimBromBeere it does compile. The C# compiler generates a managed pointer to `x` and modifies through that pointer. Managed pointers are what underlies `ref` and certain other compiler magic. – usr Mar 08 '16 at 12:36
  • @xanatos Indeed, however for `List` this won´t work. I thought array works similar. – MakePeaceGreatAgain Mar 08 '16 at 12:38
  • @HimBromBeere for list the indexing is a method call. You can't reach into a list and modify in place. – usr Mar 08 '16 at 12:39
  • 1
    @HimBromBeere No, arrays are handled directly by the runtime. The `[x]` indexer is "native" of the IL language. `List` doesn't have this this luxury, and its indexer is built at the IL level through methods (the `Item` indexer method) – xanatos Mar 08 '16 at 12:40