views:

368

answers:

6

I'm stuck in an "advanced" ASP.NET class right now and my instructor just put forth an opinion that I'm not sure about. (I say "advanced" because he's still using HTML tables for page layout and we just talked about the incredibly advanced topic of Master Pages. I need eye bleach!)

He states that instead of, say, creating a Person class that contains all of the data and methods applicable, you should create both a Person struct and and Person class. The struct contains what would normally be the properties for the Person class, and the class contains only methods. Since the Person struct sits on the stack, the data associated with your person goes away as soon as your method or whatever pops off of the stack instead of being garbage collected on the heap as with an object.

This is supposed to save memory and make the garbage collection process faster.

The question is: How big of an effect could this produce and is it really worth it?

+10  A: 

To be totally honest I don't believe you will see much of a performance benefit from doing this. Structs are hard to write well and a poorly written struct is far more dangerous than taxing the garbage collector.

It sounds like your professor is advocating the use of data transfer objects which would encourage the separation of state and behavior. This can be a good design if done properly (and in most cases you would implement this pattern using classes, not structs).

The reason I say that using a struct may be more dangerous is that value types are handled much more differently by the CLR and if written poorly (e.g. a mutable struct) can create terrible headaches. Also, if your type contains many fields and then is passed from method to method you will be copying every field's value on each method call thus using more memory than if you had used a class in the first place.

Andrew Hare
A: 

Honestly, that's the first time I've heard of that approach.

From what I understand, structs are value types. In general, you want to define a struct if it's less than 16 bytes, is immutable, won't have to be boxed, and represents a single value similar to a primitive type.

MSDN, where Microsoft has published structure design guidelines.

Classes like your instructor is talking about will easily extend past the 16-byte rule. And it's hard to see a struct of this nature not encapsulating business (or, at the very least, validation) rules in the properties. That'd be a pretty shoddy design, in my opinion.

Mike Hofer
A: 

The problem with this approach is that objects (instantiations of classes) have a mutable state. Structs in contrast should be immutable, meaning they do not have a state that can be changed. In a typical application, the Business Layer heavily utilizes the changing of the state of an object (i.e. workflows, validation, etc.).

The benefits he's describing do not warrant the drawbacks that this will bring on.

Joseph
Structs are immutable and don't have state? Since when?
jalf
@jalf Sorry about that, I meant to say "should be". Typing too fast =P Thanks for the catch!
Joseph
Structs are not (automatically) immutable. They usually should be, but that requires an effort.
Henk Holterman
-1 Structs can be designed to be immutable but are not by default. Also immutability does not mean lack of state, it means that the type lacks the ability to mutate (change) the state it *does* have.
Andrew Hare
@Andrew Good points, I will reword to illustrate what I mean more clearly. I meant that the Business Layer relies on the ability for business objects to "change" their state in order to accomplish the things that the business layer does.
Joseph
@Joseph - I removed my downvote as per your edit :)
Andrew Hare
@Andrew Thanks, and thank you for your critiques as well!
Joseph
+2  A: 

It sounds pretty silly to me. I'm not sure how much stock I'd put in the coding advice of someone who's using tables for layout in HTML. If this was a technique that produced significant advantages it'd be a standard practice. It isn't. This is the first time I've heard of this technique.

Terry Donaghe
My HTML skills are terrible too, but I don't think it reflects on my C#.
Henk Holterman
He's teaching an HTML class though and teaching worst practices. My html skills are pretty crappy too, but I don't teach other folks. Didn't mean to be snarky - just that if someone is teaching classes using worst practices for one thing it raises questions about the rest of what they teach.
Terry Donaghe
He's teaching ASP.NET, not HTML. Admitted, that requires some HTML skills. But in a small demo a <table> layout could be excusable, provided you mention CSS and DIV's.
Henk Holterman
I mentioned them, in fact, and he seemed incredulous that anyone was actually using them for layout instead of tables.
Shea Daniels
+1  A: 

Regardless of whether that strategy is more efficient, it will be more difficult to work with and I would try to avoid it. That being said, I doubt this would be more efficient. If it was, the compiler would probably implement it this way automatically. It's generally safe to rely on the compiler to do language-level optimizations.

Dan Goldstein
+5  A: 

There are several issues with the reasoning presented for pattern you describe.

First, structs are not always allocated on the stack. They are only stack-allocated when the are parameters to or local instances within a method. A struct that is defined as a member of a class is actually heap allocated. So the argument that a struct is more efficient because of the reduced effort for garbage collection is only true in certain narrow contexts.

Second, any non-ValueType members of a struct are also allocated on the heap (such as strings). So even if the struct can simply be popped off the stack, any heap objects it reference must still be garbage collected.

Third, structs rarely save memory since when passed around as method arguments they have value-semantics. This basically means that a copy of the struct is created and passed, and not a reference to the existing struct - this can't be less expensive on memory. When you see other responses that say that mutable structs can be problem - it is for the reason (along with a few others) that since structs are passed by value, changes to the original struct aren't available to locations that made a copy of the struct. This can lead you to violate assumptions or expectations within a program where you may have actually desired reference semantics for the struct.


Personally, I find the pattern of creating DTO objects (whether classes or structs) to nest within your business tier objects to be one that doesn't seem to have much benefit. Unless you have a persistence or presentation layer that specifically leverages this pattern to pass information across tiers, I don't see much value.

Furthermore, the specific case of using a struct as the DTO object seems flawed, because it introduces unnecessary redundancy. Since structs cannot inherit other structs, you can't express is-a relationships. What do you do when you have Customer which inherits from Person. Do you repeat all of the Person properties in the Customer struct? Do you nest a Person struct inside a Customer struct? Neither approach is ideal. If you at least used classes, you could have Customer extend Person.

LBushkin