C# Methods And Properties

C Sharp Method

Methods in C# and also in other programming languages are used to define behavior. They are used to write some focused logic used to complete a specific task and can be invoked, or called, to execute the code written inside of them. Methods inside classes have access modifiers, with the default being private. This means that the method is only available to use inside the same class. To make the method available to an entire project, you can use the internal keyword. If you were to use the public keyword, this makes the method available anywhere. Let’s learn a bit more about methods, fields, events, and properties in C# now.

Return Types

All methods have a return type. What does this mean? When you call a method, it can return a value or not. If it does not, it still has a return type and we call that a void return type. If a method is typed as void, it simply means that the method doesn’t return a value to the calling code. Here is an example of a method with a return type of void.

When the code above is invoked, it does not return a value and therefore it has a type of void. Notice there is no return statement. The code listed below however does use a return statement. When the ComputeStatistics() method runs, it returns an object.

Methods May Take Parameters

Methods may have one or more parameters in their method signature, or definition. Don’t get parameters and arguments mixed up however. We refer to data passed to a method as a parameter in its defining code, and as an argument when the method is actually called. Parameters in C# area typed. This means we specify the data type of the parameters that will be passed to the method. Consider this code here.
static void WriteResult(string description, float result)

The code above takes two parameters. The first has a type of string, and used the name of description. So inside the method, description is going to hold a string data type. It also has a parameter of type float with a name of result. So again, inside the function any time you see result, you know it will contain a float data type.

C# Method Signatures

The signature of a method consists of a method name and the type and kind of each of its parameters. This is a unique identifier to the C# compiler. The method signature does not include a return type. Any legal character can be used in the name of a method. Method names typically begin with an uppercase letter. The names chosen should be verbs or verbs followed by adjectives or nouns. This helps identify that a method performs an action.

Methods Can Be Overloaded

Methods have the ability to be overloaded. What does that mean? It means that a method can have the same exact name of another method, and the C# compiler will be ok with that. The rule however is that each method with a same name must differ in the type or number of parameters that the method accepts. An example of an overloaded method that is a part of the C# language is the commonly used WriteLine() method. In Visual Studio, we can even see that intellisense gives us a message that Console.WriteLine() has 18 overloads.
C# Example Overload Method

It is the signature that makes these methods unique, even though they have the same name. So you are actually calling a different method based on whether you are passing in say a float, int, or string value.

Let’s add a new wrapper method to our application named CustomWriteLine(). What this method will do for us is accept a description of the program results as well as the value of the result itself. Inside of the CustomWriteLine() method is a call to Console.WriteLine which uses string interpolation to output the data. This allows us to customize the format of the data we output.

Now when the program runs we can see that the output is exactly what we are looking for. Nice!
C sharp string formatting

Properties And Fields

Fields: Fields are used to store data, or state, inside of a class. They are basically variables, but live inside of a class. In our little application we currently have a Name field in the StockPortfolio class and it is defined using public string Name;. Since it is public anyone can change the name of the StockPortfolio. A bit of a more advanced way to handle this is to actually make the field private instead. This hides or encapsulates the data so that no code outside of the class has direct access to that field. Why would you want to do this? Well, by taking this approach you can protect and validate any data that gets inserted into an object. That is a good thing. Here is an example of code that uses a private field.

The code above uses a private field of type string. By convention, you’ll often see a private field using the leading underscore to give a visual indication that this is a private field. So this field is inside of a class named Dog, and in the constructor for Dog a developer needs to pass a name in order to create a Dog object. The constructor then saves the name in the private field making it available for the rest of the object to use. This field is also a readonly field. This means only the code in this class can assign a name via the constructor. Trying to set name to a new value in any other method other than the constructor would throw an exception by the C# compiler.

Properties: A property in C# is almost like a field but it has getters and setters which are a really cool way to manage what happens when reading or writing data to that property. These accessors are often used for validation to ensure the data is safe and clean. Let’s see this in some code.

This code still has the private field called _name. What’s different is we now have a property called Name. In C#, both property and method names should start with a capital letter. Notice the get and set accessors in this property. In the get accessor is a simple return statement that returns the value in _name. The value returned needs to be a sting since the property is defined as a string. In addition to the get accessor is a set accessor. The set accessor is arguably more important than the get accessor. This is because this is where validation logic can be placed to ensure the right data is stored in _name. We don’t want anyone trying to set _name to null or to an empty string. This type of code is often used to validate an incoming value before you assign that value into the object.

If you like you could also make use of an auto-implemented property in C#. This type of property has no logic associated with it. It only uses the get and set keywords with no additional code. The C# compiler automatically creates a field to store the value for this property. It will automatically read that field during a get operation and write to that field during a set operation. This is handy if you don’t need any special logic, but still want the benefit of a getter and setter.

We can add this type of approach to our StockPortfolio class like so.

So the purpose of properties over fields is so that you can write logic inside of a get accessor or a set accessor. The get accessor can do some operations on the data or just retrieve some field value and return it. The set accessor can perform validation as well as protect the internal state of an object to ensure that someone isn’t giving you a value that you don’t want. Properties maintain the state of our various objects in a program.

C# Events

one publisher multiple subscribers
Events are a really cool feature of the C# programming language. Events can be used to interact with pieces of the application that do things at times we might not know of in advance. If you’re familiar with events in JavaScript, the concept is similar. Imagine a button in the UI of an application. We want to be made aware of any time a user clicks that button so that we can take an action in the software. It is not known when the user may click the button, but we do need to be notified if it does happen. Another scenario might be listening for a web hook of some time. We want to be notified if there is ever a POST request made to a certain endpoint so we can take an action. These types of scenarios are good for events. Events allow objects to make an announcement to any part of the application that is listening. The announcement is the event and the object from which the announcement is made is the publisher of that event. On the other end of this is the subscriber to the event. This is the part of the application that is interested in listening to any event announcements, and then taking an action. There can be many subscribers to one event. Imagine a user clicking a button, and as a result, an action is logged to a database, an email is sent to an administrator, a file is saved to the filesystem, and an alert is displayed on the screen. So you can have multiple independent pieces of code that all get put into action based off of one event announcement. How does this work in C#? Via Delegates!

Delegates In C#

Delegates are where the fun stuff starts to happen in C#. An easy way to think of Delegates is if you are familiar with how JavaScript works. In JavaScript, you can assign a function to a variable. Then, you can call the variable name like a function. You can do the same type of thing in C# by using Delegates. The variable itself holds executable code in the program. To sue a Delegate in C#, you first create a Delegate Type. Creating a Delegate Type is not all that different from how we used the class keyword or the struct keyword to create a type. When creating a Delegate you will use, you guessed it, the delegate keyword during the type definition.

We’re going to add a delegate to our program, so we can start by adding a class file to the project and just name it as a delegate. This delegate represents any time the name of a portfolio in the program changes.

Next, we can add a public field in the StockPortfolio class that references our new delegate like so.

This means that we can now make use of that delegate in our class. So in our case, what we want to do is to make an announcement any time the name of a StockPortfolio changes. That means we can dive into the Name property, specifically the setter. Anytime the _name variable gets set, we can make an announcement. Here is a start.

Now in the main Program.cs class we can assign our delegate to the PortfolioNameChanged public member that we just added to the StockPortfolio class. This line of code would look like this.

At this point, portfolio.Name gets set, then the delegate makes an announcement. At that point, we would like to have a subscriber take an action in response to that announcement. How is this done? We need to create a new method which can be passed to the PortfolioNameChangedDelegate(). Think of it like this: WhenThisHappens(TakeThisAction); So with that in mind, we will update the code to this.

The OnPortfolioNameChanged() method does not yet exist so we can create it.

We can now run the program and see what happens. It looks like it is working. When the name changes on the portfolio, a message is written out to the console explaining as much.
C# delegate example

Multicast Delegates

That was pretty cool but now we want to level up. The name changes, an announcement was made, and something happened. It is a one to one kind of thing at the moment. Remember we said however that you can have one thing happen, and then have multiple things happen in response to that. What if when we invoke PortfolioNameChanged() we want to trigger two, three, or even ten different methods? You can do that! Let’s see that in action.

Now when the program runs, two actions happen if the portfolio name changes. First, the OnPortfolioNameChanged() method triggers and writes out to the screen “Portfolio name changed from ‘Starting Portfolio Name’ to ‘New Portfolio Name’!”. Then OnPortfolioNameChangedSecondAction() triggers and writes out to the screen “OnPortfolioNameChanged ran, now OnPortfolioNameChangedSecondAction ran”.
C sharp multicast delegate example

Excellent! Now we can see how to make many things happen in response to one event happening.

From Delegates To Events

It usually makes more sense to make use of the event keyword when following the pub-sub style of programming. The reason for this is because exposing raw delegates is a bit more error prone. Using an event adds a bit more protection so that outside of the StockPortfolio class, the only thing that other pieces of code can do is add a subscriber to this event or remove a subscriber to this event. If we were using just delegates it would be possible to do an assignment which would null and void all other subscriptions and we probably don’t want that. So all we need to do is add the event keyword like so.

Event Conventions

We want to make one more change to how we have our events set up in the application. Instead of passing two strings PortfolioNameChangedDelegate(), we should follow a popular convention of including the sender of an event as a parameter. If the StockPortfolio class makes an announcement that the name has changed, it should send itself as the first parameter. The second parameter will also be an object containing the arguments to the event. To do this, we’ll first create a new class like so.

Once that class is created above, we need to update the PortfolioNameChangedDelegate() to accept the sender and args objects instead of two strings like it was prior.

Now, StockPortfolio.cs will need to be updated to reflect this change like so.

The last thing we need to do is to update the Program.cs file to reflect that we are now using those two objects as parameters instead of two strings like before.

Running the program now gives us some interesting output. When the program starts, the name is initialized to ‘Starting Name’. Then, when we assign a new name we see our event fire and the message “Portfolio name changed from ‘Starting Name’ to ‘Warren Buffet Portfolio’!” appears. We change the name again, and the event fires again giving us a new message of “Portfolio name changed from ‘Warren Buffet Portfolio’ to ‘Bootleg Capital’!”.
C# event object sender convention

C# Methods And Properties Summary

In this C# methods and class properties tutorial, we learned a lot about the different members that can be part of a class. We saw that properties and fields are used to store state, or data, inside of an object. Of course, methods are used to perform actions, and can be overloaded. In other words, two methods can look like the same exact method, yet they are different based on the number and type of parameters they accept. This is referred to as the method signature, which uniquely identifies a method to the C# compiler. Even though method names may at times appear like they are duplicated, every single method is unique in .NET based on the method signature.