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

Started by
337 comments, last by paulecoyote 17 years, 1 month ago
[warning][warning]

Is the workshop dead? Well i have some questions to bring it to live :P.

How can i create a class, so that i can have 1 main class as basis for other classes so that this works:
Unit
Specific Type of unit with initialized variables
Second specific type of unit.
etc.
?
If i crate 3 different units of the same type must i do this?:
unit Unit1 = new unit()
unit Unit2 = new unit()
unit Unit3 = new unit()
unit UnitX = new unit()
right?

How can i avoid pre-programing this so that the names Unit1-x of the new instances get set automatically depending on how many units i want?

What if i want to create a specific unit instead of a base unit?
unit.archer Archer1 = new unit.archer()
unit.soldier Soldier1 = new unit.soldier()
Would this work?

I also notice that when i use console.WriteLine("My name"); i keep fulling the screen with text. Is there a way to clean the console of text without loosing any work, variables, classes etc?

Using enum looks easy, but when it comes to getting the data out of the enum list and storing it, i am confused.
If i use this:

public enum Who
{
Me,
You,
Us
}

And then i later want to use "Us" form the enum, get the value "Us" assigned to the variable Who? Or should i create a new variable to store "Us"?

Advertisement
Hi alvarofrank
I apologize for my english, itsn't my first language...
To answer your questions i think that :
1) You could create an abstract class(Unit) and some derived classes like 'archer' and so on..

public abstract class Unit{

public void move();
}

public class archer: Unit{
// Method Override..
public void move(){
..do something usefull..
}
}
and so on..
2) If you're going to create some instances of the same class you could use arrays..
Unit[] army = new Archer[4];
3) To avoid preprogramming instance names (Unit1 to X) you could just try:
public class Builder{

Unit[] squad;

public method buildSquad(int numElem){
for(int i=0 ; i<numElem ; i++){
squad = new Archer("Archer"+i);
}
}
}
I mean to use a Constructor whose parameter is a name for the instance..

4) About enums :
public static void Main(){

// myNum is just a kind of 'Label'
Console.Writeline(Who.Us); //will return 2
// or
int i = Who.Us; // int now has value 2
}



[opinion]
Quote:
You could create an abstract class(Unit) and some derived classes like 'archer' and so on..


Please, do not do this. You're hardcoding the various profession info into the class. You're also making it so that you cannot effectively use units without knowing their subclass, which involves reflection or casting trickery or other design problems. It's also difficult to introduce new professions and far more difficult to change professions.

Instead, make a class which has the profession info (name, capabilities, stat bonuses) which the generic unit has as a field. You can then load from file (or hardcode to start) the group of known professions. Making an Archer is then simply:

ProfessionInfo Archer = new ProfessionInfo();// Set name, other dataUnit Joe = new Unit();Joe.Profession = Archer;//// *** Advanced ***//// And eventually you'll have the professions in a container so that you//  don't need to create one every time. Just specify a key and get//  the pre-built definition.//


[/opinion]

And Console.Clear() clears the console iirc.
Quote: Original post by alvarofrank
[warning][warning]

Is the workshop dead? Well i have some questions to bring it to live :P.

How can i create a class, so that i can have 1 main class as basis for other classes so that this works:
Unit
Specific Type of unit with initialized variables
Second specific type of unit.
etc.
?
If i crate 3 different units of the same type must i do this?:
unit Unit1 = new unit()
unit Unit2 = new unit()
unit Unit3 = new unit()
unit UnitX = new unit()
right?

How can i avoid pre-programing this so that the names Unit1-x of the new instances get set automatically depending on how many units i want?

What if i want to create a specific unit instead of a base unit?
unit.archer Archer1 = new unit.archer()
unit.soldier Soldier1 = new unit.soldier()
Would this work?

I also notice that when i use console.WriteLine("My name"); i keep fulling the screen with text. Is there a way to clean the console of text without loosing any work, variables, classes etc?

Using enum looks easy, but when it comes to getting the data out of the enum list and storing it, i am confused.
If i use this:

public enum Who
{
Me,
You,
Us
}

And then i later want to use "Us" form the enum, get the value "Us" assigned to the variable Who? Or should i create a new variable to store "Us"?


The workshop is not "dead", it is only slowing down because the first two chapters were only an overview, and now people are waiting until the next chapters that will be more detailed.

EDIT: [opinion]Telastyn is absolutely right. You shouldn't mess with base class stuff like this for such a simple example, and making everything out of one class will simplify things greatly, which is a good thing for people who are just starting out.[/opinion]

1) Create a class called Unit, and then derive your other classes from that. Wait until we get to the chapter on inheritance, or go ahead and look at it now if you want a head start.
class Unit{    public virtual void Move()    {        // generic movement stuff here    }}class Archer : Unit{    public void Attack()    {        // attack stuff here    }    public override void Move()    {        // archer specific movement here    }}


2) If you want to create a bunch of units, consider using a list to store them, so that you don't have to have tons of objects around. We will probably get to lists when we get to generics, which is a rather advanced topic. A quick example:
List<Unit> units = new List<Unit>();units.Add( new Unit() );units.Add( new Unit() );


3) And so on. If your units derive from a common base class like I described before, you can also do this:
List<Unit> units = new List<Unit>();units.Add( new Soldier() );units.Add( new Archer() );units.Add( new Catapult() );


4) You should use enums like a multiple-choice list. For example, lets say that you have a Map class, which contains a Terrain enum, for specifying the current terrain type:
enum Terrain{    Grass,    Water,    Hills,    Mountains}class Map{    public Terrain terrainType;}


Now, you can set the map's terrain to a predefined type, which the compiler will enforce for you:
Map map = new Map();map.terrainType = Terrain.Grass;


Hope it all helps!
Mike Popoloski | Journal | SlimDX
Thanks Guys it has been of great help. The console command also helps a lot. I have read About inheritance and other topics as well but its sometimes to put it t practice. Deriving unit types from a major unit type sounds usefully and this too:
Quote: Unit[] squad;

public method buildSquad(int numElem){
for(int i=0 ; i<numElem ; i++){
squad = new Archer("Archer"+i);
}
}
}
I mean to use a Constructor whose parameter is a name for the instance..
Quote: Original post by alvarofrank
Thanks Guys it has been of great help. The console command also helps a lot. I have read About inheritance and other topics as well but its sometimes to put it t practice. Deriving unit types from a major unit type sounds usefully and this too:
Quote: Unit[] squad;

public method buildSquad(int numElem){
for(int i=0 ; i<numElem ; i++){
squad = new Archer("Archer"+i);
}
}
}
I mean to use a Constructor whose parameter is a name for the instance..


There is really no reason to use inheritance in this case, as pointed out by Telastyn. It would be much easier and more elegant to just do something like this:
class Unit{    // NOTE: You should wrap these in properties, I am just using fields to    // simplify things    public string Name;    public int AttackPoints;    public int DefensePoints;    public int Speed;    public Unit(string name, int attackPoints, int defensePoints)    {        // blah blah blah    }    public void Attack( Unit enemy )    {        // blah blah blah    }    public void Move( Terrain currentTerrain )    {        // blah blah blah    }}


And then just create each unit with a different name, such as "Archer" or "Soldier", etc.
Mike Popoloski | Journal | SlimDX
Greetings All,

The workshop appears less active because there are few people, including myself, posting follow-up information, and there are less questions coming in because we opted to take two weeks on the first "week" of the workshop instead of one. But, I chose to take two weeks instead of one for 2 reasons:

1. When IM'ing and speaking with the "complete beginners" of the workshop, I got the general impression that they were horribly confused and stuck on such topics as "what's a variable" and "what's an identifier". I encourage all the experienced C# programmers to take a stab at writing clarification posts to help out those who are just beginning to program.

2. The other reason I decided to extend week 1 for another week was due to technical reasons. Several people have pointed out how difficult it is to sort through 300+ posts in a single thread to determine if a question you asked has been answered, or worse, if your question has already been asked by someone else and THEN answered. To remedy this problem Superpig is currently researching a way to give the Workshop its own area here on GDNet, allowing for sub-forums, etc...This would enable us to have multiple threads per week, within a sub-forum designated for that week.

Once that occurs, people can easily see which questions have been asked, which have been answered, and if we agree to put (B), (I), or (A) at the beginning of thread titles, we can even narrow down which threads are applicable to which audience based on whether the question is for beginner, intermediate, or advanced C# programmers.

But I can assure you the workshop is not dead. I am currently in the process of writing review questions, exercises, and project descriptions for the coming weeks. I'll be updating my week 1 overview within the next few days, and Week 2's thread will be posted this Sunday on schedule.

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
Its really hard to keep up with all the threads looking for info, questions and stuff + the enourmous amount of pages we have to read.. I can say for myself that read the forum about 4 times :P

So, I would like to ask some questions:

I'd like to know when exatcly is a static constructor executed?
According to my understanding so far I know that a instance constructor is executed whenever you create a new instance of that class, but what about with static constructors??? does it start only one time, when the first class is instanciated, is that it???? Or is it executed like in compile-time?

Algo how can I create a user define type that has one-dimensional or two-dimensional array?
Can I just store them all in a local object array and then get the itens as in the following example from the book? is that valid?

public object this[int index] {		get {			return items[index];		}		set {			items[index] = value;			OnListChange();		}	}


So if I need to get the values from the array, I would need to cast the type? as its beeing stored in a object array?

Thanks in advance
blog: www.brasilokau.com/games/blog
Quote:
I'd like to know when exatcly is a static constructor executed?
According to my understanding so far I know that a instance constructor is executed whenever you create a new instance of that class, but what about with static constructors??? does it start only one time, when the first class is instanciated, is that it???? Or is it executed like in compile-time?

Static constructors execute at run time. They execute once (per AppDomain), some time between when the application domain is loaded and before any aspects of the class are used (before static variables are accessed, before instance constructors run, et cetera). The execution of the constructor is "lazy" in that respect -- you know it will run before anything else in your class (except for static variables that are initialized as part of their declaration, e.g., static int foo = 40;, which always execute before the static constructor), but you don't know exactly when it will run.

Quote:
So if I need to get the values from the array, I would need to cast the type? as its beeing stored in a object array?

The method you provided would work, but would be storing the objects as an object[], which incurs the overhead of boxing/unboxing and the annoyance of the casts. You could write the class using generics (which will be covered in more depth later in the workshop):
class MyListOfStuff<T>{  T[] objects = new T[100];  public T this[int index]  {    get { return objects[index]; }    set { objects[index] = value; }  }}
Quote: Original post by BrasiLokau
Its really hard to keep up with all the threads looking for info, questions and stuff + the enourmous amount of pages we have to read.. I can say for myself that read the forum about 4 times :P

So, I would like to ask some questions:

I'd like to know when exatcly is a static constructor executed?
According to my understanding so far I know that a instance constructor is executed whenever you create a new instance of that class, but what about with static constructors??? does it start only one time, when the first class is instanciated, is that it???? Or is it executed like in compile-time?

Algo how can I create a user define type that has one-dimensional or two-dimensional array?
Can I just store them all in a local object array and then get the itens as in the following example from the book? is that valid?

public object this[int index] {		get {			return items[index];		}		set {			items[index] = value;			OnListChange();		}	}


So if I need to get the values from the array, I would need to cast the type? as its beeing stored in a object array?

Thanks in advance


Static constructors are basically one shot methods that are guaranteed to run before any other member of the class is called. If you don't ever call or access a member of the class, it won't ever run. As soon as you do access the class, it will run the static constructor first.

The way you are doing it now for your list is how it was handled back in the .NET 1.0 days, with objects like ArrayList, which still exist in the framework. The new .NET 2.0 way is to use generics, which are very useful, and also rather intuitive once you take a little time to understand them.
Mike Popoloski | Journal | SlimDX

This topic is closed to new replies.

Advertisement