1

In some code base I am working in, initially a simple type was implemented similarly to this (I can't post exact code but to the purpose of this question, the shown code is perfectly equivalent):

class S {
    public String Name { get; }
    public S() : this(null) { }
    public S(string name) { Name = name ?? ""; }
    public Blah Frob() { .... }
}

Later, there was an undocumented change where the type was changed to a value type:

struct S {
    private String name;
    public String Name { 
        get => name ?? ""; 
        private set => name = value; }
    public S(string name) { this.name = name; }
    public Blah Frob() { .... }
}

I know perfectly well the diferences between value types and reference types but I'm not really sure what could be the reason that made this change seem the right thing to do. What are the benefits of an immutable value type that holds only a reference to another immutable reference type when compared to the equivalent refence type? What am I missing?

I seem to recall Eric Lippert commenting once to a question as to why string wasn't a struct along the same lines; what was the benefit of a struct that held only one reference to a reference type, but I can't find it anymore.

InBetween
  • 32,319
  • 3
  • 50
  • 90
  • How is this type used? If it is used a lot in small scopes only (e.g.: temporary variables in methods) it might be intended as an optimization to reduce garbage collection pressure? – UnholySheep Aug 20 '20 at 08:47
  • @UnholySheep but how does it reduce garbage collection? The GC will still have to collect the reference type held by the struct... I'm not really sure if that is a significant win. – InBetween Aug 20 '20 at 08:49
  • 1
    Does this answer your question? [When should I use a struct rather than a class in C#?](https://stackoverflow.com/questions/521298/when-should-i-use-a-struct-rather-than-a-class-in-c) – Athanasios Kataras Aug 20 '20 at 08:49
  • @InBetween but it will only have to collect the `string` objects, it will no longer have to collect any objects of type `S` - which can (depending on the exact situation) improve performance – UnholySheep Aug 20 '20 at 08:50
  • 1
    It _could_ be an attempt to optimize memory usage (see also https://codeblog.jonskeet.uk/2011/04/05/of-memory-and-strings/) or a performance optimization (structs MIGHT live on the stack) but it depends on the usage pattern for this type. Definitely something shouldn't change without a proper review/documentation, unfortunately it's almost impossible to _guess_ what the programmer was thinking about if they didn't write about it. – Adriano Repetti Aug 20 '20 at 08:53
  • 1
    For someone to to change a class to a struct, they would likely know where its being allocated (stack or heap), what the benefits of using them in hot paths can be, they would have a good understanding of garbage collection and also struct copying penalties and associated limitations, how to pass them by reference using the in keywords and all manner of other techniques., They would have ideally benchmarked their code to get fine grained optimization and minimal allocations... Otherwise, they just wasted their time and yours with little to no benefit at best, and possibly worse performance – TheGeneral Aug 20 '20 at 08:54
  • We can do nothing but speculate on the reasons, and as such I'm voting to close the question as a duplicate of "When should I use a struct rather than a class in C#?", although "too broad" would also apply. But you know *who* knows exactly why they changed it? The person who made the change. If you're using git you can use [`git blame`](https://git-scm.com/docs/git-blame) to see who made the change. If you're using any other version control software, there are probably ways of finding the same information – MindSwipe Aug 20 '20 at 08:56
  • Not exactly what you described, but perhaps [this answer](https://stackoverflow.com/a/9315211/8967612) is what you are referring to? Also, here's [another answer by Eric Lippert](https://stackoverflow.com/a/15469723/8967612) to a post with a very similar situation. – 41686d6564 stands w. Palestine Aug 20 '20 at 08:56
  • @AdrianoRepetti Thanks for the link. That could be the reason, I'll have to look into it in detail. – InBetween Aug 20 '20 at 08:58
  • 1
    The type in question is small -- eight bytes -- immutable, and logically a value; why would it *not* be a value type? Those are precisely the conditions in which we wish to use a value type. – Eric Lippert Aug 21 '20 at 03:09
  • 1
    More specifically, it appears that the intention of the type is to add semantic information to a string: this string is a name. Wrapper types that add semantic information are a common use of value types; consider enums, for example, which are wrapper types around ints that add semantics. – Eric Lippert Aug 21 '20 at 03:11

0 Answers0