Stop Using Structs Everywhere

by chris 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.

Currently rated 4.3 by 3 people

  • Currently 4.333333/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

Kodefu

Comments

Add comment


 

  Country flag

biuquote
  • Comment
  • Preview
Loading



Powered by BlogEngine.NET 1.4.5.0
Theme by Mads Kristensen

Whois KodefuGuru

Chris Eargle

Chris Eargle
.NET Community Champion

LinkedIn Twitter Technorati Facebook

MVP - Visual C#

INETA Community Champions

Community blogs & blog posts

I am a #52er


World Map

Party with Palermo

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 2009