|
Richard MacCutchan wrote: As others have mentioned, global variables tend to cause more problems than they solve; don't use them. He can get his "global" accessibility by creating a static class. I don't understand (and have never seen) a global static class present problems.
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
A static class is a very different animal.
|
|
|
|
|
#realJSOP wrote: I don't understand (and have never seen) a global static class present problems
You've lived a very sheltered life
|
|
|
|
|
Or just maybe, I've never abused the construct.
In all actuality, I was annoyed with the lack of support for global vars when I moved from C++ to .Net, but I adapted.
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
I've seen too many cases where other people have abused it, and it makes for some really nasty code.
The better (not good, just better!) code ends up being more about convenience than it does about expressing a cohesive purpose. The worse stuff just screams "I can't figure out another way to do this." Compound that many times over the span of the entire app and the lack of comments or any documentation and, yeah, it gets ugly.
|
|
|
|
|
Brian_TheLion wrote: it seems that you need to keep within certain rules to have the program compile. Well, that's true of ANY language.
Brian_TheLion wrote: Maybe some programs are better suited to C# than others. That's not true at all.
Brian_TheLion wrote: All programs seem to have a user interface as I've never come across a program that only runs under the DOS prompt. Again, not true at all. Having a GUI is pretty much dependent on what/who the app is for. I've written several command line apps in the last four months for our DBAs to run from SQL Agents. These apps didn't need a ui.
Brian_TheLion wrote: I'm being drawn towards C++ as it does allow global variables compared to C#. If you want global vars, simply create a static Globals class and add the properties and methods you need in it. I do it all the time. In point of fact, EVERY app I write has a static Globals class for that very reason.
FWIW, I transitioned from unmanaged C++ to C# back in 2007. It's really not that difficult to do.
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013
|
|
|
|
|
As a note.
If you want to learn how to create games then I would suggest finding one of the game frameworks and using that. There are adventure frameworks but others as well. Using one of those and creating a games (plural) provides a better understanding of the 'domain' for creating games.
If you want to learn OO programming and you are using an adventure game as an excuse then learning the rules for the programming language (singular) is going to be your actual goal. The game itself is unlikely to be viable because without a detailed understanding of the 'domain' both from the business layer and the development layer your initial attempts will have problems with structure. And I speak from experience on that having attempted more than a couple games when I first started. But that is not a detriment because that will aid you in the future as you will understand intrinsically why something doesn't work versus because someone told you that.
|
|
|
|
|
Thanks jschell.
Having an text adventure game waiting to be written does give me something to aim for.
Some books and tutorials give you examples on how each of the C# commands can be used but it's when you bring everything together in a project then I find that you learn more. Step-by-step guilds in building a program are useful and I did one of those recently.
Brian
|
|
|
|
|
I've knocked up this basic template to give you an idea what people are talking about. There is a "global" object you need to track like the player and also the current location, so you can either create these as an instance of a variable and keep a hold of them, passing them to functions\events as needed, or you could create a "static" class that will hold a reference to your player object and current location object. As I said, it's the basics, you'd need to tweak for things like containers as game objects also so you could pick up a bag, or put a small bag inside a big bag etc.
public class GameObject
{
public string Name { get; set; }
public int Weight { get; set; }
}
public abstract class Container
{
public int MaxWeight { get; set; }
public int MaxItems { get; set; }
public List<GameObject> Objects { get; private set; }
public Container() : this(0, 0)
{
}
public Container(int maxWeight, int maxItems)
{
this.Objects = new List<GameObject>();
this.MaxItems = maxItems;
this.MaxWeight = maxWeight;
}
public GameObject Find(string name)
{
return this.Objects.FirstOrDefault(o => o.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase));
}
public bool CanContain(GameObject gameObject)
{
if (this.MaxItems > 0 && Objects.Count >= this.MaxItems)
{
return false;
}
if (this.MaxWeight > 0 && Objects.Sum(o => o.Weight) + gameObject.Weight > this.MaxWeight)
{
return false;
}
return true;
}
}
public class Player : Container
{
public bool Get(Container container, string name)
{
GameObject targetObject = container.Find(name);
if (targetObject == null)
{
return false;
}
if (!this.CanContain(targetObject))
{
return false;
}
container.Objects.Remove(targetObject);
this.Objects.Add(targetObject);
return true;
}
}
public class Room : Container
{
public string Name { get; set; }
public Dictionary<string, Room> Exits { get; set; }
public Room()
{
this.Exits = new Dictionary<string, Room>();
}
}
static void Main(string[] args)
{
Player player = new Player();
Room startRoom = new Room();
startRoom.Name = "Hallway";
startRoom.Objects.Add(new GameObject { Name = "Key", Weight = 1 });
startRoom.Exits.Add("north", new Room
{
Name="Kitchen"
});
Room currentLocation = startRoom;
player.Get(currentLocation, "key");
Room room = currentLocation.Exits["north"];
if (currentLocation.Exits.ContainsKey("north"))
{
currentLocation = currentLocation.Exits["north"];
}
else
{
}
}
|
|
|
|
|
Thanks very much F-ES Sitecore for taking the time to write the code. It will be very useful and I'll learn more by studying your code.
Brian
|
|
|
|
|
Brian_TheLion wrote: I'm being drawn towards C++ as it does allow global variables compared to C#. I know that it's not good to use global variables and most variables should remind within their own class but it's not always easy to design a program like this and the program I have in mind that I want to write has many varables between classes.
Yeah, that's not how you do that. There are a few approaches that are valid from a C# point of view, but by and large a variable in the global namespace is never the answer unless the language itself forces that on you (thank you, JavaScript).
There are better tools: a static container class, a service locator, or best of all dependency injection.
Brian_TheLion wrote: I have in mind that I want to write has many varables between classes. I could write it with less classes but I want to have classes for certain purposes that can be reused in other programs. It also makes the program easier to deal with when changes are made.
Good OOP uses many, many classes that work in conjunction to build a system.I suggest you take some time to learn about SOLID Programming.
Global variables also make maintenance much, much harder in complex software. Modern IDEs have made this a little less significant, but for good, flexible software you should still prefer composability to imperative structure.
"Never attribute to malice that which can be explained by stupidity."
- Hanlon's Razor
|
|
|
|
|
Hi Nathan.
I think its more out of the frustration when a outside variable is not recognized in a class and I'm wishing it was a global variable to solve the problem. But like others have said Global variables don't make good programming code.
Brian
|
|
|
|
|
Yep, that's why I mentioned other tools. I like using MEF for this:
public class MyConfig
{
[Export("MyValue")]
public string SharedValue => "This is a value";
}
[Import]
public class MyBusinessObject
{
[Import("MyValue")]
public string ConfigValue { get; set; }
}
[Import]
public class MyOtherBusinessObject
{
[Import("MyValue")]
public string Value { get; set; }
}
This requires a little bit of bootstrapping to get MEF running, but results in a concise dependency injection mechanism without the bulkiness that some frameworks have.
"Never attribute to malice that which can be explained by stupidity."
- Hanlon's Razor
|
|
|
|
|
|
The Managed Extensibility Framework. It's a built-in way to make composable applications in C#, and can double as a dependency injection mechanism.
It's not terribly hard to use, but might be a little more overhead than you want to deal with when you're starting out.
Managed Extensibility Framework (MEF) | Microsoft Docs
"Never attribute to malice that which can be explained by stupidity."
- Hanlon's Razor
|
|
|
|
|
Thanks Nathan.
MEF looks like another branch in the NET framework tree like WPF.
It's good to know that it exists. I'll take a closer look at it with the link and code you provided thanks.
Brian
|
|
|
|
|
You know, here's a much easier way, which is basically using a global in C# without the work. I just don't advise it in general, but it does have uses:
public class SomeClass
{
public static string SomeValue = "This is a Value";
}
public class SomeOtherClass
{
public string LocalValue = SomeClass.SomeValue;
}
"Never attribute to malice that which can be explained by stupidity."
- Hanlon's Razor
|
|
|
|
|
Thanks Nathan.
Looks like a lot less code.
Is there a reason why you advise against using this type of code?
Brin
|
|
|
|
|
Largely because it's hard to maintain, and very common to forget that you stuck a static property on an object 3 years ago when you first wrote the code.
It can also lead to unexpected object states when you can change a static property from outside that object, and proper value validation logic - let alone proper state checks - is often ignored in accessors.
Lastly, it's simply not an OOP approach. It's an old-school method that is more-or-less a legacy of structured programming. Yes, static properties are very cool when used to modify the behavior of a genus of objects on the fly, but that's simply not what we're doing here. IMO if you find yourself writing software like this you're not thinking about it in a way that will lead to a good end result.
If you're just learning it's fine. Use it as a tool to make something that works. Just keep in the back of your mind that you're learning the skills to do it better the next time, and that how you conceptualize your code will have a huge impact on how good your code ends up being.
"Never attribute to malice that which can be explained by stupidity."
- Hanlon's Razor
|
|
|
|
|
|
Hi Nathan.
I just noticed your link to "SOLID Programming".
There are some good examples at that site thanks.
Brian
|
|
|
|
|
Just one quest question Nathan.
You gave me a link to SOLID Programming.
In the code examples at that site they use a dollar sign in front of a variable. What's the reason for this?
Brian
|
|
|
|
|
He's using PHP for his demo. The concept of SOLID applies to all OOP languages.
IIRC that's just a required convention in PHP, but it's been a minute since I worked with it.
"Never attribute to malice that which can be explained by stupidity."
- Hanlon's Razor
|
|
|
|
|
Your quest for the "ultimate programming language" seems to be an adventure game in itself.
Except you're ignoring all the clues left by those that have come before you.
Assembler
PC Basic
Lattice C (MS C)
dBase
Clipper
VB
Cirrus (MS Access V1)
FoxPro
...
C#
The Master said, 'Am I indeed possessed of knowledge? I am not knowing. But if a mean person, who appears quite empty-like, ask anything of me, I set it forth from one end to the other, and exhaust it.'
― Confucian Analects
|
|
|
|
|
Hi Gerry.
You wrote:
Your quest for the "ultimate programming language" seems to be an adventure game in itself.
Except you're ignoring all the clues left by those that have come before you.
Assembler
PC Basic
Lattice C (MS C)
dBase
Clipper
VB
Cirrus (MS Access V1)
FoxPro
...
C#
I'm not certain what you mean.
The commands that past languages have in common are things like If, then, else, etc
Brian
|
|
|
|