Clicky

Friday 13 August 2010

How to Recruit and Vet Technical Professionals


Over the years, I’ve had several experiences of being on either side of the recruitment table. At different times, I’ve been the hiring manager looking to augment the team I’ve been leading with a skilled technical professional, and at other times I’ve been that external technical professional, with skills, experience and insights to offer the team I’d be joining. Those experiences on either end of the equation have led me to some conclusions about the best way to go about ensuring that each party to the process gets what they intend out of the deal. For the hiring manager, that’s a new and well-motivated team member that’s able to bring some desired skills into the team, and for the candidate it’s the opportunity to meaningfully demonstrate what they can do and determine what the opportunity has to offer them. Those goals aren’t in competition with one another; a “win, win” is what each party should be looking for when it comes to matching the right people to the right roles. It’s only when each party gets what they’re looking for that everyone involved (the hirer, the hired, and any intermediaries) can consider that the process has been truly successful. This article contains some thoughts on how each of the various parties to the process can help ensure a mutually-beneficial outcome.




One of the difficulties with recruiting technical professionals is that you will sometimes find yourself in the position of assessing people that have skills you don’t yet have. For intermediaries like recruitment consultancies, HR departments, and for non-technical hiring managers, you can substitute the “sometimes” in that last sentence for ‘always’, and the “do not yet have” for ‘will never be interested in personally acquiring’. That’s merely a fact of the different types of value those parties add to the process; similarly, you can be sure that most prospective technical hires will never be overly interested in finer details of employment legislation, employer branding, marketing, or abstract management theory. How, then, if you’re not a technical professional yourself, do you go about determining whether the person in front of you has what it is that you’re looking for? Before answering that question, here are some likely approaches that might seem reasonable at the time, but which, depending on how they’re carried out, may not provide the outcome you intended:


1)     Sending an intermediary to do your first interview for you

Whatever else you do, as a hiring manager my advice is not to make the mistake of letting someone else represent your company or department to prospective new employees. Your HR department and any external recruitment consultancies you may engage can certainly take the marketing burden out of sourcing suitable candidate CVs for you, and they can also provide a screening service to ensure that you don’t need to deal with the initial sift of wholly-unsuitable applicants yourself, but they’re not there to conduct any actual interviews or assessments on your behalf.

Typically, what an agency will do when they receive a brief from a hiring manager is they’ll advertise for suitable candidates using the job spec you provide on several of the industry-specific online recruitment websites such as JobServe, etc. The agency will remove your company’s name and identifying details from their listing, so that any less-reputable candidates and competitor agencies wont attempt to contact you directly. The recruitment consultant will sift the CVs they receive in response to their advert, will discount any outright unsuitable applicants (e.g., you’re looking for a Java guru, and it turns out the candidate has made coffee once), and they will conduct a brief telephone screen with each short-listed candidate to make sure that their stated skills, salary aspirations (or daily rate, for a Contractor) match with what you’re looking for. A good HR professional or external recruiter will also be able to give you as hiring manager advice on the state of the skills market, average salaries that other organisations are paying for roles similar to the one you’re recruiting for, and will be skilled at extending and negotiating a mutually-beneficial package when it comes time to do that. Make no mistake about it, though: for all the value they can add, your recruitment consultant or HR professional isn’t in a position to conduct an in-depth technical interview or make a recruitment decision for you, and they’re not there to represent what you have to offer to the candidate – that’s your job.

Interviews are a two-way street, and if you make the mistake of letting your department be represented at a first interview by someone that doesn’t even work in your department, don’t be surprised if the most marketable candidates fail to be impressed by having to run a gauntlet of your intermediaries before even getting to meet an actual decision maker, and opt out of your process before you get a chance to assess them.


2)     Getting the candidate to write some code using a pen and paper.

It’s certainly useful to get a candidate to write code at some stage in the interview process (and this is in fact something that many good developers look for in the recruitment processes they’re subjected to – an employer that tests their ability to write code not only gives them a chance to prove themselves, but also gives them some confidence that their colleagues-to-be will be as skilled as they are, having come through a similar process themselves: more on this later). In my experience, though, it’s never a good idea to ask a developer of any level of experience to write code using a pen and paper. Doing so is akin to asking a skilled chef to cook you a meal.......with their feet. Which is to say, it’s simply the wrong tool for the job, and not in any way indicative of the relevant skills you should be looking for.

An analogy I use when highlighting why pen and paper is the wrong medium for assessing an ability to write useful code is the telephone. Up until the mid-nineties, most people were able to remember lots and lots of their friends’ telephone numbers off by heart. It wasn’t an uncommon nor an especially useful skill, it was just a somewhat abstract and unusual ability that everyone had spontaneously acquired because of the limitations of the way the telephone medium worked back then. These days, in the age of near-ubiquitous use of mobile phones, less and less people choose to remember such meaningless lists of numbers off by heart. Instead, everyone tends to use the standard address book function on their mobile phone to attach meaningful text labels to the people with whom they wish to communicate, and look up those labels whenever they need to make a call. You often find people looking up numbers on their mobiles these days, even when they’re using a desktop phone, because it’s become the modern paradigm of how to efficiently access that category of information. The essential skills of how to use a telephone and how to have a meaningful conversation with another person that you can only hear but not see are still the same today as they were in years gone past; it’s merely the tertiary skills surrounding the medium that have evolved.

With reference to the above sociological changes that have come about as a result of advances in telephony technology, asking a developer to write code with a pen and paper is a bit like attempting to assess a person’s ability to use a telephone by asking them to write down all of the telephone numbers they know off of the top of their heads. In much the same way as telephone handsets have evolved, development environments have changed a lot in the past 15 years too. Round about that same time in the mid-nineties that everyone in society possessed ubiquitous Rainman-esqe abilities to recall lists of essentially meaningless numbers in order to be able to communicate using the telephone, developers once had to remember most of the syntax of the languages they worked with in their heads. These days, in the age of smart Integrated Development Environments (IDEs), that’s not the case any more. With the advent of Intellisense, Code Snippets, Templates, and Keyboard Shortcuts, there are many more efficient ways of coding today than there were even five years ago, and new tools are becoming available all the time. These days, if developers want to insert a Constructor into a class they’re designing in C#, they don’t need to recall the exact format of such a code fragment from memory, they can just type ctor, hit tab, and all of the syntax for a parameterless Constructor that is meaningful within the context of the class they are creating is inserted for them. The real skill isn’t in remembering the syntax, it’s in knowing what a Constructor is, when to use one, and in understanding why a parameterless one can be overtly implemented in a class but not in a struct. When you can’t quite remember which namespace one of the 3,500-odd pre-defined .Net Framework classes resides within, the latest development environments will help you by suggesting ‘Imports / using’ directives that you may have missed. When you create a custom class in a project, provided you’ve been smart enough to structure your project logically using folders, the Visual Studio development environment will create meaningful namespaces for you. These cues, and many others, allow developers to concentrate on the important part of their job – creating innovative, robust and reliable solutions to well-defined problems – and relegates the non-cognitive and repetitive parts of the process to the place where they belong: the subconscious.

Asking a developer to undertake a pen-and-paper coding exercise never reveals any of that relevant knowledge, insight or craft. Instead, it obstructs many good developers from demonstrating the meaningful work they can do inside a real development environment that takes care of the repetitive, irrelevant and non-creative parts of the process, and lets them focus on the meaningful work they’re actually good at: producing useful, stable, innovative solutions.


3)     Trivial Pursuit

Nearly as bad as using pen-and-paper coding, is having a list of trivia questions associated with the skill of interest, and asking the prospective developer a pre-set list of abstract multiple-choice questions. Generally speaking, interviewers do this when they don’t have an in-depth knowledge of the topic themselves, because it provides an easy way for them to understand whether the answers they receive are ‘right’ or ‘wrong’, without the interviewer having to understand why they may be right or wrong themselves.  It’s not advisable to go down this route, for two reasons. Firstly, to be blunt, it’s pretty disrespectful to the interviewee; if you don’t understand the answers to the questions you’re asking yourself, how can you be certain that the questions and the way you’re framing them makes any sense to someone that is actually knowledgeable on the subject? Go down this route, and it’ll quickly become clear to an experienced candidate that you don’t know what you’re talking about, and are merely repeating what’s written on a piece of paper in front of you parrot-fashion. That in turn will ruin their confidence in your ability to assess them meaningfully, and even if they do ‘pass’ your test, you may very well find the best candidates will opt out of your process as a result. Secondly, even if the developer isn’t put off by being quizzed by someone that clearly doesn’t understand the subject themselves, a process based on the ability to recall abstract facts fails to address the fundamental difference between knowledge and intelligence. I’ll take an intelligent developer that has yet to acquire knowledge in a given area over one that has learned to recite stock answers to set questions but has not one iota of ingenuity and creativity about them any day of the week, and twice on Sunday.

In short, if you use set lists of coding trivia that you don’t really understand the answers to yourself in a misguided attempt to assess your candidates, whilst you may end up with someone that would do very well on a VB Pub Quiz Team, you’re just as likely to end up with an individual that couldn’t implement an IPissup interface within a Brewery class if their lives depended on it. You may find to your horror, after they come on board, that they are not after all the learned experts you supposed, but had merely read the same three articles on Wikipedia as you used when compiling your list of questions.

Finally, I would strongly advise against using ‘online tests’ to assess candidates. Such ‘tests’ tend to have all of the abstractness, lack of context, and general irrelevance of the in-person version of the Meaningless Trivia Test, but are even less personal than the in-person variety.


4)  Getting the candidate to do some real work

Getting close to the way I recommend doing things now, but with caveats. The best developers, like any skilled professional, are happy to demonstrate that they can do the work you’re asking them to do. They welcome employers (or customers, in the case of contractors) exercising meaningful due diligence that allows them to demonstrate they’re the right person for the job. As I mentioned earlier, this is something that many of the best people actively look for in a recruitment process, because as well as giving them an opportunity to prove themselves, it also gives them confidence that their colleagues will be every bit as on their game as they are. Good people want to work with other good people, from whom they can learn and share knowledge, and alongside whom they can grow and develop as ever-more experienced professionals. The fly in the ointment is that there are a small number of less-reputable organisations out there, also advertising jobs, that are only too happy to ask for samples and free work, without ever intending to recruit. For such organisations, unfortunately, it’s a ‘creative’ way of saving on their training budget by getting an external professional to give some free demos under the auspices of an interview, or of getting small projects done for free. For this reason, you need to be careful; you don’t want to chase good people away by coming across as a freeloader.

One good way of avoiding your organisation’s honourable intentions being misconstrued, is to not make providing a sample of the candidate's work the very first stage in the process. Interview the person first, and invest some of your time to show them a little of what you have to offer them as an employer, before asking them to invest their time in providing free work for you. That approach immediately makes you stand out as an organisation that’s serious about recruiting. Organisations that are instead only looking for freebies, generally make it obvious by asking prospective candidates to invest their time in providing a demo solution after only a short telephone screen, and well before the organisation has demonstrated that it has anything of substance to offer the right candidate. Less reputable organisations will also have the cheek to ask for second and third samples of work, and changes to work submitted, never attempting to explain why earlier demos didn’t satisfy their ostensible purpose of demonstrating the candidate’s technical ability. I advise those on the hiring side of the recruitment table never to behave this way; not only will it be entirely obvious to people with marketable skills that you’re merely freeloading, but the best people can and will inform their equally-skilled professional colleagues about their experience with your process, and it’s very likely that you’ll be left with only sub-standard applicants should you become serious about recruiting at any point in the future. Reputations are hard to win, and easy to lose; for candidates, for employment brands and for internal and external recruiters of all flavours alike.




So much for the ‘wrong’ ways to go about finding the right people to join your fold. Now, the right way. As touched upon above, the best people will welcome you engaging in due diligence. There’s no better way to do this than by getting your existing technical staff to speak with the prospective new member of the team. Ideally, on your side of the interview table, as a minimum, you’ll have your lead developer or development manager (whatever nomenclature you use within your particular organisation, they should be the person your most senior management are most likely to go to when they want an opinion on how anything technical should be tackled within your organisation).

Invite your prospective new employee in to speak with you and your lead tech informally for a first interview (or a telephone screen, if distance is an issue), and don’t beat them up during that initial interview. The first interview should be to establish just two things: one, whether the person in front of you is manifestly unqualified for the work concerned, and two, to give them a taste of what you have to offer and to let them know what you expect in return. That’s it for the first meeting; those are the only goals. The aim isn’t to establish whether they’re exactly right for your organisation just yet, and it’s not to make any hasty decisions based on limited information. During your conversation, ask them to tell you about something particularly innovative that they’ve worked on recently, or better still their pet project; every developer has at least one on the go, and, whilst they’ll mostly be commercially irrelevant to your business, they’ll tell you a lot about how well your prospective new colleague is able to communicate the concepts they understand to others.

As mentioned earlier, I strongly advise against asking coding trivia questions from a set list, but it’s perfectly acceptable to have your internal technical expert ask the candidate to explain more about the nuts and bolts of the candidate’s pet project or most recent work. This is why you have your best existing internal technical resource on your side of the interview table; they should be able to probe and question during a discussion of the design, without coming across as needing to be the smartest person in the room. Your technical expert should avoid the temptation to ask the candidate any ‘trick questions’, that rely on obscure technical knowledge that they’ve only just encountered themselves, but it’s OK to probe a little to see how deep the candidate’s knowledge of underlying concepts is. It’s also OK to ask about newer technologies that the candidate may or may not have encountered; if they’ve not, you’re looking for them to tell you so rather than for them to waffle or bluff their way through – knowing what they don’t know is a good trait in a developer. Your internal technical expert may not know everything that the candidate does about the subject at hand, especially if the candidate is intended to add a skill to your team that it hasn’t yet mastered, but there should be enough common ground for your tech lead to determine whether the candidate outright doesn’t know their subject area.

After that first interview, ask suitable candidates to participate in a coding task. You can choose to allow your candidate to do this at home, or within your premises; it shouldn’t matter which to you, although bear in mind that some developers wont have access to all of the tools at home that they’re used to having in their workplace. The developer should have access to every resource they’ll have available on the actual job, including the internet, any reference books they want, MSDN, etc. They should also have a reasonably-powerful development machine, similar to the one they’d be using if they were to be recruited. Make sure that the problem you ask them to solve is realistic, and can be developed by someone with reasonable skill in the area you’re recruiting for within 3-4 hours max. Ideally, get one of your existing developers that wasn’t involved in designing the exercise to try out the problem first, to be sure it’s of a reasonable level of difficulty. Make it obvious to your candidate that you’re not asking them to do unpaid commercial work, by presenting them with an abstract problem that is clearly unrelated to your business (e.g., perhaps ask them design a Windows Service that writes an entry to the event log every time the sum of the minutes in the current time is a prime number, or something similar). It’s not usually possible to present candidates with a real commercial problem, because even if it’s something your team has actually tackled within a set time frame, chances are you brought existing knowledge to your understanding of the problem that brand new candidates wont be able to draw upon.

After your candidate has completed their solution, get them to talk through their design with you, and review it with them in the same open and non-critical way that you’d conduct internal code reviews on real, commercial pieces of work. Doing this will not only tell you a lot about how the candidate approaches technical tasks, it will additionally give you an insight into how well they work with others as part of a mutually respectful and co-operative team. If done properly, it’ll also give the candidate a good insight into your culture, and help you both to decide whether or not you’re a good fit for one another. What you should be looking for in an ideal candidate isn’t just a window onto their existing knowledge, but their ability to apply what they know to new problems, whether they have the honesty and self-awareness to recognise what they don’t yet know, and, of key importance, whether they have the initiative to find things out as and when the need arises. Those are all key traits that a set list of coding trivia questions or a faceless online test would never tell you.

After your ‘technical review’ with the candidate, discuss your findings internally amongst the recruitment team. Subsequently, if you decide to proceed, have one, final interview with the candidate, to review all that you’ve learned about one another in a post-mortem type setting. Ask them about their experience of your process, discuss any issues that you’d like to clarify with them, and be prepared to take any questions they’ll have of you. This meeting is about rounding out what you know about one another, and finalising any missing details.

Once you’ve completed the above process, your internal ‘recruitment team’ (consisting of the hiring manager, your internal technical expert, and any advisers from HR that you’ve consulted) should be in an excellent position to decide whether the person in front of you is a right fit for your needs or not. Don’t be tempted to conclude that just because you’ve come all the way through the process, you need to extend an offer; psychologists call that phenomenon ‘justification of effort’. Remember that your process is designed to give you the information you need to make an informed decision, and to give a favourable impression of your organisation to everyone that has taken the time to apply. It’s not merely about picking the last person standing.

Put any candidates that have made it to the end of your process into three categories: first choice, any second choices, and any unselected candidates. Contact unselected candidates right away, to thank them for their time, and to tell them they haven’t been selected. Keep any second choices in reserve whilst your external recruiter extends and negotiates a mutually-agreeable offer with your preferred candidate (hiring managers should never do this part themselves – negotiation is skill that most hiring managers don’t have, and, even when they do, this process is still at its most effective when conducted via an intermediary). If an offer can’t be agreed with the preferred candidate, approach any second preferences and try to come to an agreement with them.

At the end of the process, let every candidate that hasn’t been selected know the outcome, and, if they’d like to know, the reasons for your decision. The classiest way of doing this is for the hiring manager to call each individual personally, to thank them for their time, and to express regret that they weren’t the right person on this occasion, followed up by a letter to confirm the news. Many hiring managers shy away from doing this, perhaps through fear that the candidate will react badly. In my experience, though, most if not all professional candidates really appreciate it when the organisations in which they’ve invested their time and effort take the time to conclude the process properly. In years of informing people in person when they’ve not got a job, I’ve never once had the experience of a candidate reacting with anything other than courtesy and appreciation that I had enough respect to let them know the outcome myself, when I called to let them know the decision. If you’re unfortunate enough to experience a candidate being aggressive, or treating the call like a debate rather than a simple communication of your decision, feel free to end the call quickly – you’re not there to be their career counsellor, and you’re not there to justify yourself beyond respectfully communicating your decision, and your reasons for making that decision if the candidate is interested in hearing them. Conclude matters this way, and you’ll always have a steady stream of candidates for jobs that you may advertise in the future; word gets around about which organisations treat candidates well and which don’t, and it’s amazing how often that candidate that wasn’t quite right for you yesterday, has exactly the right skills for the position that comes up tomorrow, or knows someone that does. End things well, and you’ll always have the ability to open dialogue again if it becomes relevant to do so.


Thursday 12 August 2010

Structs and Classes


.Net provides two basic object types that can be used to construct more complex objects: Structs and Classes. These object types are made up of similar features, and can be used to fulfil many of the same tasks as one another. There are, however, some important distinctions between what you can do with Structs and with Classes, and between how similar features are implemented differently by each object type. This article describes those similarities and differences, and provides some suggestions for when and how to use each type.



The Similarities


Structs and Classes are both capable of utilising Fields, Properties, Constants, Methods, Events, Handlers and certain types of Constructor. They are both capable of being instantiated, and they are each able to have variables declared as being of the type they define. Both can model data objects, using much the same syntax in each case, and indeed you can often convert a Struct to a Class and back simply by changing the word struct in its definition to class, or vice-versa. Both types of entity may also implement Interfaces.


The Differences


The most fundamental distinction between Structs and Classes is rooted in a .Net concept known as the Common Type System. When you compile a program written in any of the languages that target the .Net Framework, the first step that happens is that the code gets converted by the specific compiler for the high-level language (e.g., C#, VB, C++, or whatever) into something called Microsoft Intermediate Language (also known as the Common Intermediate Language, often abbreviated to ‘IL’ for short). The IL representation of a .Net program is then converted into a set of platform-specific machine code instructions by the .Net runtime execution environment, known as the Common Language Runtime (CLR).  [ NB: For Java developers, the concept of .Net’s IL is analogous to the way that Java compilers convert raw Java code into Bytecode, to be run within a Java Virtual Machine.] 

Part of what makes the process of converting any of the languages that target the .Net Framework into IL possible, is the fact that each of those different languages uses the Common Type System (CTS) mentioned above. The CTS defines the basic set of types (boolean, integer, etc) that IL understands and knows how to work with. [Actually, the set of types that IL understands is far larger than any of the languages that presently target the .Net Framework is capable of modelling, and not all of the languages that target the .Net Framework implement exactly the same subset of those IL types, leading to the potential for subtle language interoperability issues, but that’s a discussion for another day.]

The key point of relevance to the subject under discussion is, there are two core types defined within the CTS, which are known as Value Type and Reference Type respectively. Every type in any .Net program derives from one or other of these two possible base types, and which one they derive from dictates how they will be stored in memory, how the object may be inherited, and how objects that are of those types will behave.

Getting back to Structs and Classes, it’s the case that every Struct defined in a C# or VB program is considered to be a Value Type by the CTS, and every Class is considered to be a Reference Type at the very root of its inheritance chain. This difference in base type inheritance is what accounts for many of the differences between Structs and Classes, which are listed below:


Differences in Implementation Inheritance


As noted above, both Structs and Classes may implement Interfaces. However, only Classes may overtly use Implementation Inheritance to inherit from another object. Classes, unlike Structs, may also be inherited by another object.

At their root, Structs derive from a CTS type called System.ValueType, which in turn inherits from System.Object. Classes with no overtly-defined base inherit directly from System.Object (and, for Classes that don't inherit directly from System.Object, there may be any amount of Classes in between System.Object and themselves).

Concentrating on Structs, you may find it surprising to know that most of the defined system types in C# and VB (e.g., integer, double, decimal, etc), also derive from System.ValueType, and are in fact implemented as Structs. If you mouse over the keyword of any data type implemented in this way within C# or VB, this fact becomes readily apparent:


System.ValueType doesn’t add any functionality to Structs that is not also available to Classes through their common inheritance from System.Object, but it does replace some of the functionality present in System.Object as virtual methods with implementations that are more appropriate for Structs.

Structs, in short, are intended to be used for tasks that require allocating small, fixed-size chunks of data, that need to be able to be accessed and changed rapidly, without incurring an undue performance hit in managing the memory resources that are allocated to them. That’s why they’re used to implement the basic data types such as integer, etc. : when a developer defines an integer variable, they expect to be able to begin using that variable to store numbers within the permitted range for that type immediately, without needing to mess around with allocating space in memory by using a new() operator as a separate activity each and every time, and without checking whether any modifications their application makes to the value stored in the variable has had any implications for the amount of memory required. They want to be able to access any values placed in their variable readily, without having to rely on the underlying implementation to use pointers to look up an address in memory, then decide what has been stored there, as a two-stage process. Structs enable developers to achieve this rapidity of declaration and access to memory chunks of a fixed size, but the trade-off is that they can’t be used to achieve true Implementation Inheritance, which would require management of an area of memory of a variable size.

So, whilst Structs are easy to consume and fast to access, if you need to use Implementation Inheritance, that’s a clear sign you need to use a Class instead.   


Structs can be consumed without explicit instantiation, Classes cannot


When you create a variable of a type defined by a Class, you need to use the new() operator to instantiate that object before you can access the properties of the object  the variable represents. With Structs, this is not the case. Take the following simple example, using a struct:

public class StructsAndClassesDemo 
{
    static void Main()
    {
        MyStruct myVariable;
        myVariable.SomeInteger = 1;
        Console.WriteLine(myVariable.SomeInteger);
    }
}

public class MyClass 
{
    public int SomeInteger;
}

public struct MyStruct 
{
    public int SomeInteger;
}

This will compile and run correctly, outputting “1” in the Console window. If, on the other hand, we change the Main() Method to:


a compilation error will occur, since we have tried to use an uninstantiated variable of a Reference Type.

NB: You still need to instantiate an object of type struct before you may access Properties (as distinct from Fields) of that object.


Variable Assignment works differently for Classes than for Structs


Because Structs are Value Type objects, variables of types defined by Structs behave somewhat differently than variables of types defined by Classes. Consider the following simple program:

public class StructsAndClassesDemo 
{
    static void Main()
    {
        MyClass myVariable1 = new MyClass();
        MyClass myVariable2;

        myVariable1.SomeInteger = 1;
        myVariable2 = myVariable1;
        myVariable1.SomeInteger = 2;

        Console.WriteLine(myVariable2.SomeInteger);
        Console.ReadLine();
    }
}

The above example would output “2” in the console window.  If we instead exchange the usage of a Class type object for a Struct, and keep the variable assignment logic exactly the same:

public class StructsAndClassesDemo 
{
    static void Main()
    {
        MyStruct myVariable1;
        MyStruct myVariable2;

        myVariable1.SomeInteger = 1;
        myVariable2 = myVariable1;
        myVariable1.SomeInteger = 2;

        Console.WriteLine(myVariable2.SomeInteger);
        Console.ReadLine();
    }
}

The revised program will output a “1” in the console window instead.

This highlights a key difference in the way that Value Type and Reference Type objects are treated in memory. Reference Type objects (in this case, Classes) actually represent a pointer to an address in a part of the computer’s memory known as the Heap. When assigning one variable to be equivalent to another variable, as happens in the line  myVariable2 = myVariable1, what happens in the case of the variables concerned being of a Reference Type is that it is the pointer to the relevant address on the Heap that gets copied to the variable being assigned to, not the actual data that is contained at the address itself. An upshot of this is that when the variable that has been assigned from, in this case myVariable1,  subsequently gets updated so that its SomeInteger field takes on the value “2”, myVariable2 in effect gets its value updated as well, since it is the object that resides at the location in memory that is being pointed at by both myVariable1 and myVariable2 that has been modified.

Values associated with variables of Value Types such as Structs, are stored in a different place in memory, known as the Stack. In the case of Value Types, assigning one variable to be equivalent to another does copy the actual data from the object being assigned from to the object being assigned to. Because of this, when the object that has been assigned from is subsequently updated, the effect of this change is not felt by any variable that had previously been assigned to by that variable. This is why the value “1” is returned in Console window in the second example above, in contrast to what happens when the types being considered are Reference Type variables based on custom Classes.


Classes can have overt Parameterless Constructors, but Structs cannot


As was mentioned earlier, you can use a Struct without explicitly instantiating it using the new() operator. It’s also the case that you may use the new() operator if you wish (which has the effect of instantiating the whole object for use, including any Fields the Struct may contain, by calling an instrinsic parameterless Constructor for the Struct). However, when you’re designing a Struct, it is erroneous to overtly define a parameterless Constructor for the Struct, since one is declared behind the scenes by the C# or VB compiler for you. You may still create additional Constructors that do take parameters. So, whilst the Constructor:

public class MyClass 
{
    public MyClass()
    {
        SomeInteger = 99;
    }

    public int SomeInteger;
}

is fine in a class, a similar Constructor for a struct would result in a compilation error. You may only provide a parametered Constructor for a Struct, like so:

public struct MyStruct 
{
    public MyStruct(int intialIntegerValue)
    {
        SomeInteger = intialIntegerValue;
    }

    public int SomeInteger;
}

The reason for disallowing overtly-defined parameterless Constructors in the case of Structs is that the CLR, as part of that trade off of rapidity of access for completeness of memory management mentioned earlier, does not guarantee to call such Constructors for Value Types, and so any code you place in such a parameterless Constructor would not be guaranteed to run once the program was fully compiled. This is down to the same phenomenon that makes it possible for the Fields of Structs to be accessed and set without initialisation; if the compiler spots an optimisation for your code such that you are only accessing the Fields of a variable that is of a type defined in a Struct, it will not bother generating the IL to call the Constructor for that Struct, and will instead make assumptions that the Fields you are accessing will contain meaningful values. Curiously, if creating the IL directly yourself, it would be perfectly possible to create a parameterless Constructor, and have it run every time, regardless of any apparent optimisation that may be possible, but then if you had a task that required a Constructor to run every time, that’d be a pretty clear sign that what you really needed to use was a Class. For now, in the trade off of best speed for true object orientation in the case of Structs, the designers of the VB and C# languages have decided to take the simplest route, and have prevented parameterless Constructors from being defined for Structs altogether.

You cannot initialise a field within the definition of a Struct


Both Structs and Classes can have Fields. In the case of Classes, it is possible to give a Field an initial value within the definition of the Class itself, like so:

public class MyClass 
{
    public int SomeInteger = 99;
}

Trying to do the same within the definition of a Struct, however, will produce a compilation error:


The reasons behind this difference in the way that Structs and Classes are permitted to operate cuts right to the heart of the different ways these distinct types of object are treated in memory. For Classes, because their values are physically stored on the hardware’s Managed Heap, and because .Net’s Garbage Collection mechanism deals with managing resources on the Heap, the CLR can guarantee to have cleared the area in which objects defined by Classes will be stored before placing any new object in that area. Because of the Garbage Collection process, the CLR can be sure that the Properties and Fields of any objects defined as Classes will either be null, or that any values they do hold will have been deliberately assigned to them. CLR is therefore happy to have Class –type objects that have a mixture of assigned and as-yet-unassigned Fields and Properties.

The Stack, on the other hand, where Structs are stored, is much less well managed (and, as a trade-off, it is generally much quicker to access and modify resources placed there). However, because there is no Garbage Collection process going on in the background to manage that area of memory, Structs will generally be assigned to a random area of the Stack, big enough to contain the Struct, but where the CLR cannot guarantee that any values placed in that area of the Stack have been deliberately assigned to the Struct that now resides there, or whether the area in memory that happens to currently be assigned to a given Field or Property of a Struct was actually a piece of data from another unmanaged object that was left behind when that object was cleared from the Stack at some prior point.

In an effort to mitigate the uncertainty about the whether parts of a Struct have been deliberately set or are merely a throwback from prior use of the same location of the Stack by some other unrelated object, Structs are restricted to having their fields initialised in a certain controlled way, that can be efficiently checked by the compiler. If you use the implicitly-defined Constructor, new MyStruct(), to create a new instance of a Struct, this has the effect of setting all of the Struct’s Fields and Properties to their default values (so, 0 for int -type Fields, etc). If you define your own parametered Constructor for a Struct, the compiler will warn you if you fail to initialise any of the Struct’s Fields within that custom Constructor:


As mentioned earlier, you don’t need to initialise a Struct at all before you begin to assign values to it. If you do use a Struct –type object in this way, and you fail to assign a value to one of the Fields of that Struct variable before assigning the value of that variable to another variable of the same type, you will also get a compilation error:


By removing the possibility that Fields may be set within the definition of the Struct itself, it allows the compiler to efficiently focus on other more straightforward possible places (i.e., within a Constructor, if one is used, or within the scope of a variable defined to be of the type the Struct declares, if no Constructor is used), to determine whether all of the Fields of a Struct-type object have been fully initialised before those Fields can be accessed by or assigned to any other object.

Structs may not have a Destructor


Because instances of Structs exist on the Stack and not on the managed Heap, the concept of Destructors (i.e., an overt override of the Garbage Collection mechanism to allow the developer to specify how to dispose of temporary resources) clearly does not apply to them:





So, in summary, the differences between Classes and Structs are:

·        Classes are Reference types, whilst Structs are Value Types.

·        Classes are physically stored on the Managed Help, whilst Structs are stored on the Stack.

·        The effect of variable assignment works differently for Classes and Structs.

·        Both types of object can implement Interfaces, but only Classes may overtly employ Implementation Inheritance.

·        Structs cannot have overt parameterless Constructors, Classes can.

·        When you define your own parametered Constructor for a Struct, the compiler enforces that you must explicitly set the value of any Fields within that Constructor to avoid said Fields containing spurious values. For Classes, the compiler entrusts the Garbage Collection process with this task.

·        You must instantiate a variable based on a Class, whilst you may instantiate an object based on a Struct (though you don’t have to).

·        Structs may not have default values for Fields, Classes may.

·        Where you choose not to instantiate a Struct –type variable, the compiler will enforce that you must set each Field of that instance of the Struct before you can use the variable for assignment.

·        Structs may not utilise Destructors.


Because of these different characteristics, Structs should be used most often for small structures, where the values contained therein will not be frequently re-assigned between variables, thereby creating a lot of duplicate data in memory, and where there is no need to use Implementation Inheritance.

Classes should be used where a more complex object that will be frequently passed around between parts of the program needs to be modelled, and in instances where it doesn’t matter that assignment between variables copies a reference to the object being assigned from, rather than the underlying data of the object itself being assigned.