Lesson Objectives
At the end of this lesson, you will know…
- How to create a property in a class that uses one of your other classes as its datatype.
Adding properties with custom datatypes
Currently, all of the properties in our classes are either strings or integers. But sometimes we need to store something more complex in a property.
For example, in the Location class, we want to possibly store an item required to enter the location (such as a key). If there is a quest available at that location, we need to store that value. We also might have a monster that exists in that location.
So we need to add some new properties to the Location class, to store these values.
Step 1: Start Visual Studio Express 2013 for Desktop, and open the solution.
Step 2: Edit the Location class, in the Engine project. Add these new properties:
public Item ItemRequiredToEnter { get; set; } public Quest QuestAvailableHere { get; set; } public Monster MonsterLivingHere { get; set; } public Location LocationToNorth { get; set; } public Location LocationToEast { get; set; } public Location LocationToSouth { get; set; } public Location LocationToWest { get; set; }
Now we have properties to hold these values for each location. Because we need to store an Item object in the ItemRequiredToEnter property, its datatype is Item. Just like using a string datatype when we want to store some text in a property.
Step 3: Now, let’s add parameters to the constructor to accept some of these values and save them to the properties. Change the constructor code to this:
public Location(int id, string name, string description, Item itemRequiredToEnter = null, Quest questAvailableHere = null, Monster monsterLivingHere = null) { ID = id; Name = name; Description = description; ItemRequiredToEnter = itemRequiredToEnter; QuestAvailableHere = questAvailableHere; MonsterLivingHere = monsterLivingHere; }
Notice that after each of the new parameters, there is ” = null”. Some locations won’t have an item required to enter them, a quest available at them, or a monster living there. This lets us call the Location constructor without passing these three values. The constructor will know to use the default values, which, in this case, is the “null”. So, both of these lines would work the same way:
Location test1 = new Location(1, "Your House", "This is your house"); Location test2 = new Location(1, "Your House", "This is your house", null, null, null);
Step 4: Edit the Quest class, in the Engine project. Add this new property:
public Item RewardItem { get; set; }
The RewardItem property will store what item the player receives when they complete the quest.
NOTE: In the video, the parameters in the Location class constructor are on two lines now, and that’s OK. Since the last character of the first line is a comma, the computer knows that the next line is a continuation of the first line. I just did this because that line was getting long, and a little difficult to read.
In C#, the end of a line is signified by a semi-colon “;”, a closing parentheses “)”, or a closing bracket “}”.
Summary
Now you can create properties that hold more complex values. This way, you’ll be able to do things such as get the name of the monster at the location, without needing to do extra lookups somewhere outside of your object.
Source code for this lesson
Next lesson: Lesson 10.1 – Creating collections of objects
Previous lesson: Lesson 08.2 – Using class constructors with derived classes
All lessons: Learn C# by Building a Simple RPG Index
Next and Previous lesson links are mixed up! 🙂
Oops! Thanks, they should be in the right place now.
Step 4 says to add this to the Quest class:
public List QuestCompletionItems { get; set; }
I understand now, but it was confusing at the time because we don’t yet have a QuestCompletionItem class so this line generates an error. In lesson 10.1 we create the QuestCompletionItem class, and then in step 4 of lesson 10.1 you repeat the instruction to add this list to the Quest class, so you could probably delete this from this lesson.
Also the video doesn’t show you entering the 4 “public Location LocationToNorth { get; set; }” properties, or doing step 4.
I’m really enjoying the tutorial, thanks!
Thanks for pointing that out. When I was making the lessons, I ended up moving some parts around, from one lesson to another.
Why don’t we put LocationToNorth and the like to public Location(…..) ?? I’m confused why this is so. Also, a bit back track but why do we have private Player _player when we don’t do it for any other class?
There are a couple reasons I did it this way.
First, if we had parameters for the LocationToNorth/South/East/West values in the constructor, then we’d be required to pass in values for all four parameters when we instantiate a Location object. And most locations don’t have another location in all four directions.
We could get around that by passing in “null” as the value for directions that don’t go to another location, but I didn’t want to introduce that in this lesson.
Second, in order to create the “home” Location object, we’d need to have already created an object for the “town square” (to pass in as its LocationToNorth). However, we wouldn’t be able to create the “town square” object until we created the “home” object, because the “home” Location would need to be passed in as its LocationToSouth.
This is called a “circular dependency”. You can’t create A until you have B. But you can’t create B until you have A.
When you get to Lesson 11.1 “Using a static class”, the PopulateLocations function creates the game’s locations and sets them up with their connected locations.
I put the answer to your other question in the comments for Lesson 05.1, as a response to your question there.
In “Location.cs” code, this line:
public Location(int id, string name, string description, Item itemRequiredToEnter = null, Quest questAvailableHere = null, Monster monsterLivingHere = null)
On the sections “= null” there are red lines saying “Default rarameter specifiers are not permitted”.
Is this normal? When I build the program, three errors are counting.
It sounds like your project is using the 3.5 .Net framework, instead of the 4.0 version. Try doing this:
1. In Visual Studio’s Solution Explorer (upper right section) right-click on the “Engine” project and select “Properties”.
2. In the “Target framework” section, select “.Net Framework 4”.
3. Save the solution and try to re-compile it.
Let me know if that works for you, or not.
Hi,
First of all, I really enjoy this tutorial. I have some basic C# knowledge and your tutorial helps me understand the more advanced stuff.
I noticed that the code written in this lesson, at step 4 cannot be found in the source code from the next lesson. Is this correct?
Thanks,
Syll
Thank you. What code (which class) do you think is missing? I did not notice anything when I looked last night. But I might have missed it.
I am referring to the Quest class and the following line is missing: public Item RewardItem { get; set; } in this source code: https://gist.github.com/ScottLilly/582dc1e93794d4d3c48e
Ah, yes. I must have looked at the 9.1 lesson last night. I’ve got it fixed now. Thanks for letting me know about it!
You mention in Step 4: Add this line of code to Quest class: ”
public Item RewardItem { get; set; }
but in the next tutorial (Video 10.1) at 6:52 when you go to the Quest Class, that line of code is not in there. I worry I might have overlooked something.
Hi Bryan,
Thanks for catching that and letting me know about it. The RewardItem should still be in the Quest class. I’ve added a note to the lesson, and the video, to let everyone else know.
what is this: public List QuestCompletionItems { get; set; }
My program doesnt compile and i don’t see this in video or in under video.
Please help me to understand
You can remove that property, or complete the next lesson (10.1). That property has been moved to the next lesson, when we add other List properties.
Hello
Could you explain me why property functions use class name as data type?
because I don’t understand how it works.
Thank you.
Are you asking about the datatype for a property, or for a function?
For a property: A property is used to hold a value. We need to declare the type of data (datatype) to store in that property. If we want to store an integer in the property, the datatype is “int”. If we want to store a string, the datatype is “string”. But, we can also store other types of objects in a property. In the code for the Location class, we want to be able to say that a monster lives at a Location. So, we will create an instance of a Monster object. We want to store that Monster object in a property. So, we need to declare that property’s datatype as Monster – because it will hold a Monster object.
For a function: The datatype for a function tells what type of object the function will return, after the function does its work. If the function does not return a value, you use “void” for the datatype.
Does that make it clear for you?
Hello
My question was for a property.
Now it is clear.
Thanks Scott.
Hey
First of all very good tutorial. 🙂
I have a nonChapterRelated question.
In the classes Monster.cs Location.cs and Item.cs you use propertys with the same syntax:
public int ID{get;set;},public string Name{get;set;}, etc
a) how come there is no interference? Since all the classes are in the namespace Engine?
and/or all the propertys are Public?
b) Can i asume that, as long as i create each class in a new page, i can keep using the same variables without actualy reffering to the other (‘same named’) variables?
c) do things change when i use the code using.namespace at the top of a screen
edit: chapter 14.1 solved the question kinda
Hi Koro,
You’re welcome 🙂
The properties must only be unique inside the class. So, you cannot have two ID properties in the Monster class. However, you can have an ID property in the Monster class and an ID property in the Item class.
The class name (Monster, Item, etc.) must be unique inside a namespace. But, you could create a class with the same name inside a different namespace – although that is usually not a good idea, because it can be confusing which class is being used.
Is that clear?
yes ty
public Item ItemRequiredToEnter { get; set; }
public Quest QuestAvailableHere { get; set; }
public Monster MonsterLivingHere { get; set; }
public Location LocationToNorth { get; set; }
public Location LocationToEast { get; set; }
public Location LocationToSouth { get; set; }
public Location LocationToWest { get; set; }
Does the above code mean you are creating an object? If no, would you mind talking a bit on class as data types please?
Those are properties. They’re like variables for a class. They will be filled with different types of objects. The datatype of the “ItemRequiredToEnter” property is an “Item”. So, that property will hold an “Item” object. The “QuestAvailableHere” property will hold a “Quest” object. The “LocationTo” properties will hold Locations.
The Item, Quest, and Location objects are all instances of our classes. In the World class, we will create instances (objects) of these classes and put them into these properties.