Advertisement

C# Workshop - Week 1 (Ch. 1 & 2) - Advanced

Started by July 01, 2007 12:15 AM
337 comments, last by paulecoyote 17 years, 1 month ago
dusty_one: When you model an object, think of it as a noun. When you model it's methods, think of them as the verbs that the object performs. If something is performed on an object, it should not be a method of that object.

Now, public access is for things that someone could make that object do. private access is for internal mechanisms.

So let us say we were modeling a car. When you drive a car, you shift gears, you press the gas, hit the breaks, et cetera. Now, when you press the buttons and do all these things, you are using public methods. The car has an interface for you to use. Internally, the car is taking your inputs and doing calculations to determine how much gasoline to put in the engine and how much airflow to use. These are private methods -- you should not have access to these. However, when you hit the gas pedal (the public method), it may perform many of these private actions (and call private methods). But do you have access to these internal methods? No!

It is the exact same when you model the object in your software. In your car object, you can provide public access to methods to interface with the internals of the car. Perhaps "applyGas", "applyBrake", and "shiftGear". These public methods may call private methods like "determineAirIntake" and "calculateRPM". You wouldn't want these private methods accessible from the outside because not only does it not make 'sense,' but it could be dangerous and allow an unknowing user to ruin the validity (there is a better word, but I can't think of it) of an object. I mean, is there a button in your car that allows you to determine the air intake? No!

Get it?
Here's my first week's exercise. I abused the static constructor of the MyNameIs class and removed the namespace to see if it worked--and it did! This is probably a good example of bad design but it works.

class MyNameIs{    static MyNameIs()    {        System.Console.WriteLine("My name is Brandon!");    }    static void Main() { }}
-Brandon Blog | Journal
Advertisement
Let's say we have a class Foo. Now Foo is going to have what's called a helper method. Normally helper methods are private. Therefore, this helper methods is going to be used only in methods of this class. Example-time:
public class Foo{    public Foo(){        setToZero(x, y, z);    }    public Foo(int x, int y, int z){        if (x < 0 || y < 0 || z < 0)            setToZero(x, y, z);        else{            this.x = x;  //this refers to the class Foo, IOW, it refers to itself            this.y = y;            this.z = z;        }    }    public void reset(){        setToZero(x, y, z);    }    private int x;    private int y;    private int z;        private void setToZero(int x, int y, int z){        x = 0;        y = 0;        z = 0;    }};

Granted this is a silly example, but it shows how a helper method is used within a class. Normally private methods are used when the class and the class only needs to manipulate that class's data. I hope that's clear as mud.

Beginner in Game Development?  Read here. And read here.

 

Quote: Original post by shawnre
1. Do we get a listing of "correct" answers at some point?
2. Should we actually post answers here, or just compare our answers if "correct" answers are given?
3. When we do the exercises, will we have a "correct" version of the program listed? Well, I know there are many different ways to code things and achieve the same results.
4. Should we post our code for exercises in each weeks thread?


1. Yes. Friday I will post the answers I had when writing the review questions. They may still be open for debate, but they are the answers taken from the specs.

2. YES! [lol] Feel free to post a few of your answers to the review questions, if you've not seen someone answer the question yet, or if you had a different answer than the ones provided.

3. Yes. I will post a reference sample on Fridays as well. As you indicated, these are not necessarily the Correct way to accomplish something, simply a way to accomplish something.

4. If you've got an implementation which is notably different from someone else's, then feel free to post your own solution.

Ultimately, the idea is to avoid duplication while still covering a wide array of implementation styles.

Cheers!
Jeromy Walsh
Sr. Tools & Engine Programmer | Software Engineer
Microsoft Windows Phone Team
Chronicles of Elyria (An In-development MMORPG)
GameDevelopedia.com - Blog & Tutorials
GDNet Mentoring: XNA Workshop | C# Workshop | C++ Workshop
"The question is not how far, the question is do you possess the constitution, the depth of faith, to go as far as is needed?" - Il Duche, Boondock Saints
Just finished reading chapters 1 and 2 for the first week of the workshop.

Chapter 1
I felt fairly comfortable with this chapter and felt like it was quite a good overview of things. There are a few questions I would like to ask however.

1. What exactly is the .net framework and how does it work differently from for example the C runtime library - to be honest I have always poorly understood aspects like this in programming so a quick summary or links would be appreciated.

2. Of all parts of Chapter 1 I felt the least comfortable with the concept of the interface and attributes, mostly I feel it is due to not being something I have ever come across in any other programming language. Why exactly would you use interface and what is it used for - I didn't find the example shown to be very clear at all.

Could someone go through the example shown for how to use attributes in detail and explain what is happening?

Chapter 2
This was quite a dry chapter for me, I felt like I picked up only a little of what this chapter was trying to explain like the use of the prefix @ to allow you to use keywords as identifiers and also verbabim string literals. Not really much else to say about this chapter.

I'll try and have a go at answering the questions - will there be answers posted for the questions later?(already answered above)

The first exericise - I would be surprised if there was anyone who wasn't capable of completing it.
How about them apples?
I haven't got far yet, but here's a few questions.

I know this might be nitpicky, but here goes. The C++ Standard states that main() should return an int to ensure portability. How come Main()'s return type is void in C#?

Also, how would one reference a namespace within a particular scope? In the examples for section 1.5, the using statement seems to serve for different purposes (apparently it expects a variable).
Advertisement
Quote: Original post by JWalsh

public class Rectangle{    public int Area     {        get { return m_Height * m_Width; }    }    protected int m_Height;    protected int m_Width;   }



The only question I have about getters and setters so far is this: What happens if you decide later to change the Area type to float? Any code using the Area expecting an int will choke, right?

I tested this out by passing Area to a variable of type int and found it attempted "implicit conversion" and gave an error. The compiler suggested using "explicit conversion". So I'm assuming if the programmer needs to pass the Area of the rectangle to a function that uses a float, they'll use explicit conversion (type casting).

int area = (int) rect.Area;  // rect.Area changed to float; implicit conversion fails


I also tested this by passing Area to Console.Writeline() and it managed just fine with int or float. Writeline takes object[] arguments. I sorta get that (unified type system)... an array of objects that offer a string representation or somethin?

What other methods could be used to solve this issue? If this falls under polymorphism, or any other question we're not suppose to ask about yet, then just toss a hint and I'll save this question for later. :)

-Brandon Blog | Journal
@popcorn

Good questions. Let me elaborate a bit. The .NET Framework is a combination of two things - a huge library of available code, and a sort of virtual machine that Just-In-Time compiles Intermediate Language code into machine-specific code, as well as handles security issues.

This is different from the C-Runtime libraries in a few ways. First, the C-Runtime Libraries are the core libraries of the C Language that deal with memory allocation, user input, and some machine-specific instructions. But in general, when people think about using a C Library the majority of people think of the C Standard Library.

With the .NET Framework, both the "run-time" libraries as well as the "Standard Library" are combined into a single library called the .NET Framework Library. Also of interest, the C Runtime Library is designed to work with, wait for it...C. However the .NET Framework Library is designed to run with ANY language which is understood by the .NET CLR. Which seguays nicely into the next part.

The .NET Framework also consists of the .NET Common Language Runtime. This is a sort of virtual machine which takes code written in Microsoft Intermediate Language (MSIL) and converts it on-the-fly into native, machine specific instructions. This is different from the C-Runtime Library which is itself just a library of native instructions. In other words, there is no equivalent in C.

The benefit of the CLR is that any language which adheres to the Common Language Specification and has an associated .NET Compiler can be turned into MSIL, and consequently run by the CLR. The end result is that the .NET Framework Library exposes a huge but-load of components (reusable code) to a wide variety of languages. The standard 3 are C#, C++/CLR, and VB.NET, but can also include J#, JScript.NET, F#, IronPython, etc...

Regarding the two parts you had a hard time with, these tend to be the parts that confuse most people with C#. Let me take a crack at explaining.

The technical definition of an "interface" is a compiler enforced agreement between a class and its users to implement specific functionality. In other words, an interface is just a way of forcing a class to expose a public "interface" which guarantees that it will exist for its callers. For those familiar with C++, this is how abstract classes are used in C++.

Perhaps an example would be better.

Lets say I want to create a set of living objects. Lets say Humans, Oak Trees, and Sharks. Now, in order to do that I need to identify what makes an object "living". One thing which I might assume is that all living things must "breathe." Now, in my program I want to be able to tell all living things to breathe every couple seconds, but in order to do that I need to be sure that everything that calls itself living, can in fact breathe.

One such way to do that is to create a base class called "Living", and to provide a "Breath" method. This is a perfectly acceptable solution except for one problem...neither a human, a shark, nor a tree breathes the same. Additionally, there's no such thing as a "living". I mean have you ever said, "Hey dude, check out that hot looking 'living' over there?!" No, the reason being is that there IS NO SUCH thing as a "living". There are, however, examples of things which ARE living.

This immediately screams abstract class, and for those who've used C++ before, this is in fact how you'd create an interface. However, C# does something a bit more elegant, it allows creation of explicit interfaces. An interface for living might look like this:
public interface Living{    void Breathe();}public class Human : Living{    void Breathe()    {    }}public class OakTree: Living{    void Breathe()    {    }}public class Shark: Living{    void Breathe()    {    }}


Now, by deriving Human, Oak Tree, and Shark from "Living", I'm telling the compiler I WILL define a Breathe function for each of these classes. If I were to leave off the Breathe function from any of the above classes, the compiler would complain.

Now, an interface makes no assumption about HOW a class defines an interface function, just that it does. So in the above example I could make the human take a break out of his mouth, I could make the shark take a breath through his gills and then absorb the oxygen into his blood stream from the water, and I could make the oak tree...hrmm, not sure how trees breathe exactly, but take my word for it, they do.

At any rate. That's a simplified example. Once you've stated that a class "implements" an interface, and you've defined its interface methods, etc...you can treat is just like it were an instance of that interface.

In other words, you could now put trees, humans, and oak trees in a collection of "Living" objects.

Ok, my wife's telling me it's time for dinner. I'll be back later to address attributes.

Cheers!
Jeromy Walsh
Sr. Tools & Engine Programmer | Software Engineer
Microsoft Windows Phone Team
Chronicles of Elyria (An In-development MMORPG)
GameDevelopedia.com - Blog & Tutorials
GDNet Mentoring: XNA Workshop | C# Workshop | C++ Workshop
"The question is not how far, the question is do you possess the constitution, the depth of faith, to go as far as is needed?" - Il Duche, Boondock Saints
Re: Interfaces:

Interfaces exist as a compromise for removing multiple inheritance. They're limited in such a way as to make sure they'll cause no problems if multiply inherited.

For example, there's a common interface to dispose of various non-memory resources before garbage collection which you'll come across later. A network connection and a texture don't lie within the same inheritance hierarchy, but it's useful to have a common interface to do that action.


Re: Attributes:

A nice simple example uses enumerations.

Say you have an Enumeration to describe how a monster can move:
public enum MovementModes{    None = 0,    Walking = 1,    Swimming = 2,    Flying = 4}


If you make a monster which can both walk and fly, the debugger as well as the .ToString() for the enum will say "5".

Unless you'd specified the " FlagsAttribute":

[Flags]public enum MovementModes{    None = 0,    Walking = 1,    Swimming = 2,    Flying = 4}


With that attribute set, the debugger and ToString() will list a monster with Walking and Flying set as "Walking|Flying" and "Walking, Flying" respectively. Enum.Parse() will even be smart enough to set the combined flags.

I am unsure of how that magic which turns the attribute into behavior difference works.

[Observation] - User made attributes are often used along with System.Reflection.[/Observation]

There are other sort of things that attributes are used for:

- ThreadStatic which modifies a static member to be static per thread.
- Conditional which indicates the method (and calls to it) should only be compiled into builds with some condition (usually 'DEBUG')
- Serializable
- AtrributeUsage which specifies what sort of things (classes, methods, properties,etc.) an attribute can be applied to.

... and a bit more. They're used to give code snippets certain properties or information that the compiler or you can then use.
Telastyn posted a fine example of attributes so I'll just add that attributes are simply meta-data. That is, they are data which defines additional information about your classes, methods, fields, etc...which is typically used to change the run-time interpretation or representation of your data.

Once you've defined your meta-data (ie. attributes) you need code that consumes and uses the meta-data. In order to do that, you take advantage of the System.Reflection namespace to list the attributes of the member or class you're interested in, find the one you want, obtain the information, and modify the run-time behavior based upon what the meta-data tells you to do.

The tricky part with attributes is knowing when to use them. They are a very powerful feature, but until you're comfortable with the paradigm, they're an easy feature of the language to overlook.

Cheers!
Jeromy Walsh
Sr. Tools & Engine Programmer | Software Engineer
Microsoft Windows Phone Team
Chronicles of Elyria (An In-development MMORPG)
GameDevelopedia.com - Blog & Tutorials
GDNet Mentoring: XNA Workshop | C# Workshop | C++ Workshop
"The question is not how far, the question is do you possess the constitution, the depth of faith, to go as far as is needed?" - Il Duche, Boondock Saints

This topic is closed to new replies.

Advertisement