Stop Using Structs Everywhere

by KodefuGuru 5. June 2009 18:15

One thing that really gets under my skin is the overuse of structs. I hear arguments such as "structs are simple", "I don't have to instantiate it", or my personal favorite, "this is just a record." A struct can be complex, not instantiating something is not a good excuse, and structs are not "records" (usually this comes from Delphi programmers).

A struct should represent a single value. If it doesn't represent a single value, it shouldn't be a struct. That's the general guideline I follow when deciding whether or not to use a struct. In most cases, you should define a class.

Here is the criteria for making a struct:

  1. Does it represent a single value?
  2. Will the instance size be under 16 bytes?
  3. Should it be immutable (modifications actually make a new copy in memory, forcing you to pass by ref to methods)?
  4. Will this rarely need to be boxed (cast to an object)?
  5. Will it usually be short-lived?
  6. Will it mostly be embedded in other objects?

If you can answer yes to all those questions, then you may indeed have a struct on your hands.

This should be a struct:

   public struct Coordinate
   {
      
private decimal latitude;
      
private decimal longitude;

      
public Coordinate(decimal latitude, decimal longitude)
      {
        
this.latitude = latitude;
        
this.longitude = longitude;
      }

      
public decimal Latitude
      {
        
get
        {
            
return latitude;
        }
        
set
        {
            
this.latitude = value;
        }
      }

      
public decimal Longitude
      {
        
get
        {
            
return longitude;
        }
        
set
        {
            
this.longitude = value;
        }
      }
   }

A coordinate is a well-defined value, it's small, and there's no problem making it immutable.

This should not be a struct:

    public class Address
    {
        
public string Street { get; set; }
        
public string City { get; set; }
        
public string State { get; set; }
        
public string Country { get; set; }
        
public string ZipCode { get; set; }

        
public Address(string street, string city, string state, string country, string zipCode)
        {
            Street = street;
            City = city;
            State = state;
            Country = country;
            ZipCode = zipCode;
        }
    }

Although one could argue that an address is a well-defined value (I'd argue that it has too many composite parts), it is clearly going to be larger than 16-bytes. In fact, if you have even one string field, it most likely should be a class anyway.

Note that these are simple examples. Over the course of my career I've seen huge classes that are inexplicably defined as structs. Rarely have I seen a class that should have been defined as a struct.

Tags: , ,

Kodefu

Comments

6/5/2009 6:29:08 PM #

trackback

Trackback from DotNetKicks.com

Stop Using Structs Everywhere

DotNetKicks.com

6/6/2009 5:18:52 PM #

pingback

Pingback from arjansworld.com

Arjan`s World    » LINKBLOG for June 6, 2009

arjansworld.com

6/7/2009 8:22:04 PM #

pingback

Pingback from alvinashcraft.com

Dew Drop - June 7, 2009 | Alvin Ashcraft's Morning Dew

alvinashcraft.com

6/7/2009 11:11:07 PM #

Josh

Could you elaborate on the 16-bytes rule?

Josh United States

6/8/2009 7:44:44 PM #

chris

Sure Josh, I did so here: www.kodefuguru.com/.../More-On-Structs.aspx

chris United States

6/9/2009 1:58:53 AM #

pingback

Pingback from blog.cwa.me.uk

Reflective Perspective - Chris Alcock  » The Morning Brew #364

blog.cwa.me.uk

6/9/2009 1:19:04 PM #

trackback

Trackback from DotNetShoutout

Stop Using Structs Everywhere

DotNetShoutout

6/10/2009 2:21:25 PM #

Muhammad Mosa

I missed understood the title, but after reading it, I agree with you. Structs should only be used where it fits.

Muhammad Mosa Egypt

Add comment




  Country flag

biuquote
  • Comment
  • Preview
Loading



Powered by BlogEngine.NET 1.6.0.0
Theme by Mads Kristensen

Whois KodefuGuru

Chris Eargle

Chris Eargle
.NET Community Champion

LinkedIn Twitter Technorati Facebook

MVP - Visual C#

 

INETA Community Champions
Friend of RedGate
Telerik .NET Ninja
Community blogs & blog posts

I am a #52er


World Map

RecentComments

Comment RSS

Tag cloud

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2010