In this tutorial we’ll move forward with the Customer class we created in the last episode. Now we want to keep learning object-oriented fundamentals in C#, and to do that we are going to start looking at Methods. Our Customer class is going to need some methods such as Validate(), Retrieve(), and Save() to make it more useful. Properties only hold data, but if we want the class to be able to do work, we need to add these methods. We’ll also revisit the concept of constructors in C# and object-oriented programming.
Adding A Method
The first method we can create is a Validate() method. In C# you can use function syntax to create a method. We will use the public keyword so that it can be accessed from other parts of the application. This method is going to return either true or false. This is what we call a boolean. Therefore, we need to type this method as such. So right after the public keyword, we must use the bool keyword. After the bool keyword comes the name of the method which we choose, and we will call it Validate(). In the body of the method is some logic to validate the property values LastName and EmailAddress. This code is highlighted below in our crm Customer class.
Customer.cs
using System;
namespace CRMBIZ
{
public class Customer
{
public static int InstanceCount { get; set; }
private string _lastName;
public string LastName
{
get
{
return _lastName;
}
set
{
_lastName = value;
}
}
public string FirstName { get; set; }
public string EmailAddress { get; set; }
public int CustomerId { get; private set; }
public string FullName
{
get
{
string fullName = LastName;
if (!string.IsNullOrWhiteSpace(FirstName))
{
if (!string.IsNullOrWhiteSpace(fullName))
{
fullName += ", ";
}
fullName += FirstName;
}
return fullName;
}
}
public bool Validate()
{
var isValid = true;
if (string.IsNullOrWhiteSpace(LastName)) isValid = false;
if (string.IsNullOrWhiteSpace(EmailAddress)) isValid = false;
return isValid;
}
}
}
Testing A New Method
We already have a test class set up for our Customer class named CustomerTest. Let’s revisit that test class and add a new test method to confirm our Validate() method works. For brevity, we will just show the test method, not the whole Test class file. When creating automated code tests, it makes sense to have a test for valid values and a test for invalid values. This first test below tests valid values for the method. The comments give an idea of how to follow the process for tests. In other words, set up some data, take an action using the code you’re trying to test, then assert the results.
[TestMethod]
public void ValidateValid()
{
// Set up the data
var customer = new Customer();
customer.LastName = "Smith";
customer.EmailAddress = "Hsmith@greenenergy.com";
var expected = true;
// Take an action
var actual = customer.Validate();
// Assert the results
Assert.AreEqual(expected, actual);
}
In the test code above, we first create a new Customer and then populate both the LastName property and the EmailAddress property. Those two properties are required to be filled out in our original Validate() method. So since that is the case, then we expect that this will return true in this scenario. We state this with the var expected = true; syntax. Then, we call the Validate() method off of the customer object and store the return value in the actual
variable. Lastly, we use the Assert.AreEqual() method to confirm that expected
and actual
are in fact equal. And in fact, they are because our test passes when we run it.
Testing Invalid Data
The above code tests for valid data. What about invalid data? Consider that the LastName data is missing, what then? The code below shows us how we can do that. Notice that this time, when we are setting up the data, we do not populate the LastName field. This is wrong, so we expect that the Validate() method would return false in this scenario. Therefore, the expected
variable is set to false. When Validate() called, it should return false and store it in actual
. Now, expected
is false, and actual
should be false, so the Assert.AreEqual() should be true.
[TestMethod]
public void ValidateMissingLastName()
{
// Set up the data
var customer = new Customer();
customer.EmailAddress = "Hsmith@greenenergy.com";
var expected = false;
// Take an action
var actual = customer.Validate();
// Assert the results
Assert.AreEqual(expected, actual);
}
Pro Tip: To run just a single test rather than the entire suite, you can right-click the name of the test method to run and then choose “Run Selected Tests”.
We can add one more test method for invalid data. This time, we will check for a missing email address. Here is the test method for that which we call ValidateMissingEmailAddress().
[TestMethod]
public void ValidateMissingEmailAddress()
{
// Set up the data
var customer = new Customer();
customer.LastName = "Smith";
var expected = false;
// Take an action
var actual = customer.Validate();
// Assert the results
Assert.AreEqual(expected, actual);
}
For good measure, we’ll run all tests now. It looks like all tests are passing, so that is great!
Adding A Constructor
Our Customer class needs a constructor so we can tackle that now. A constructor is a special piece of code that is executed any time an instance of a class is created. In other words, every time an object is created from a class, the class constructor is run. It is named using the same name of the Class itself. Constructors should be placed at the top of the class above any properties and methods. One way to create a constructor is by using a Visual Studio snippet. By typing ctor, then tab and tab again, you will see the constructor get created automagically.
If a constructor has no parameters, it is referred to as the default constructor. All of the properties in our Customer class already default to sensible values, therefore we do not need to initialize anything in the constructor. It is possible to add additional constructors with parameters if needed. Here is the funny thing. If you don’t need to actually run any code in the constructor, then you technically don’t need it. C# will run it for you automatically in the background. Let’s add another constructor that will initialize some data. Here is our Customer class with the two new constructors we just created.
using System;
namespace CRMBIZ
{
public class Customer
{
public Customer()
{
}
public Customer(int customerId)
{
this.CustomerId = customerId;
}
public static int InstanceCount { get; set; }
private string _lastName;
public string LastName
{
get
{
return _lastName;
}
set
{
_lastName = value;
}
}
public string FirstName { get; set; }
public string EmailAddress { get; set; }
public int CustomerId { get; private set; }
public string FullName
{
get
{
string fullName = LastName;
if (!string.IsNullOrWhiteSpace(FirstName))
{
if (!string.IsNullOrWhiteSpace(fullName))
{
fullName += ", ";
}
fullName += FirstName;
}
return fullName;
}
}
public bool Validate()
{
var isValid = true;
if (string.IsNullOrWhiteSpace(LastName)) isValid = false;
if (string.IsNullOrWhiteSpace(EmailAddress)) isValid = false;
return isValid;
}
public bool Save()
{
return true;
}
}
}
Notice that use of the this
keyword in the second constructor. What that means is it is referencing the current instance of the class. Imagine you create a new customer and assign it to a variable like c1. When the constructor is called during that initialization for c1, the this
keyword is referring to c1.
If someone comes along and creates a different instance of a Customer and places that customer in c2 let’s say, then this keyword points to that new instance.
How To Add Methods To A Class In C# Summary
In this tutorial, we had a look at adding methods to our Customer class. We learned a bit about method signatures, method overloads, as well as how constructors are used.
A method’s signature is its name and set of parameters. It does not include the return type. The C# compiler uses the method signature to match the calling code to the right method. When there is more than one method with the same name, we call that overloading.
Overloading is when two or more methods have the same name, but different parameters. There can be a different number of parameters, different types of parameters, or a combination of different numbers of parameters and types of parameters. The code above shows one method taking an integer parameter and the other taking no parameters.
A constructor is a piece of code in the class that executes anytime an instance of the class is instantiated into an object. The convention is to set up the constructor as a public method of the class using the same exact name as the class itself. A default constructor is one that takes no parameters. You do not need to specifically include a constructor unless you need to initialize some values or pass some parameters to the class.