C# scope question - my GML brain doesn't compute

Xer0botXer0

Senpai
Hi !

So I've started with fun C# stuff, it's suppose to be a free fullstack suite that manages a lot of businessy things.

The problem I'm having probably stems from the way I see OOP coming from GML, I believe that you can have obj_potato and obj_sack and then reference obj_sacks.quantity variable directly from obj_potato..

but in C#, there's some annoying STATIC keyword that seems to be a great divide, sometimes the code apparently requires the class or method to be static, or the method to be static but then the class isn't and that prevents any referencing or accessing of variables.

There just seems to be a massive problem with accessing members of other classes.

Anyone know of a better way to look at C# in a way that'll shed light on this scope issue I'm having ?

It doesn't seem to be about the accessor keywords like private, partial, public and so on.
 

kburkhart84

Firehammer Games
The static keyword in C# has some similarities to the one here in GML. It means that the variable/member belongs to the actual class itself, instead of some instance of a class. It is a cheap way to make global variables(though some frown on it). So static members can be accessed using the class name(which includes executing functions as well).

For non-static members, those belong to the class instances. Those are similar to instance variables, which can be different for each individual instance of that object(in GML) or class/object in C#. You don't get to easily access those variables as easily as you do in GML, because there is no massive list of instances, and no with() statement, etc... So if your objects/classes need to talk to each other, you will need to account for that, and store references to those things.

Public and private class members simply refer to things you can or cannot access from outside of the class. If something is private, you cannot access it using dot syntax, no matter how good your reference is. However, if you have a public member function of the class, then that function can access the private variables.
 

ElectroMan

Jack of All Shades
I would argue that GML teaches some bad OOP practices in this regard. One of the pillars of OOP is encapsulation. You don't need to expose the internal state of a class for other external systems to look and meddle with directly. This makes it harder to analyse program flow and the behaviour of a given object in a dynamic setting where it interacts with dozens or sometimes hundreds of other systems. The common (and canonic way) to implement classes (different from structs!) in any OOP language is to have all member variables private and expose them only through public methods, with what is called "getters" and "setters". In fact, in C++ you can actually set any member method as "const" which gives a compiler error if you change the object state within that method. So you can imagine, setting the "getter" functions as const (or readonly) makes it much less bug prone and simplifies code analysis.

Global variables are a whole can of worms entirely. For the record, I'm not necessarily saying GML is a bad OOP language, it does its job well in teaching the basics of the object-oriented paradigm. But there are huge caveats to be made to the common code patterns you see in the wild, borne from the intrinsic permissiveness of the language, that do not translate well to other OOP languages. And this is one of them.

EDIT: Fixed public -> private, which would make the whole point moot. Thanks @Alice.
 
Last edited:

Alice

Toolmaker of Bucuresti
Forum Staff
Moderator
The common (and canonic way) to implement classes (different from structs!) in any OOP language is to have all member variables public and expose them only through public methods, with what is called "getters" and "setters".
(emphasis mine)

I think you meant to say "have all member variables private", but otherwise pretty accurate description of encapsulation. Just want to point out that in some cases - and this is especially true for C# - there might be language features that allow applying the getter/setter method concept more neatly than creating functions like "getSomeVariable()" and "setSomeVariable()'. In case of C# this is represented by so-called properties, which are very similar to fields but also allow method-like logic. Like here:
C#:
public int Left { get; set; }
public int Width { get; set; }
public int Right
{
    get { return Left + Width; }
    set { Width = value - Left; }
}
The little get/set keywords in Left and Width tell the class to expose getters/setters for Left/Width, and in case of Right getting it actually returns the sum of underlying Left and Width values, while setting it actually sets the Width accordingly.

Or if you want to set left/width only at the start and never change them (so-called immutability), you can instead do it like:
C#:
public int Left { get; }
public int Width { get; }
public int Right
{
    get { return Left + Width; }
}
No setters are exposed, so you won't be revealing it to the world.
 
See it this way: GML is "nested one level lower", as there is only just ONE class, and it's the class "gameObject".
Of course, we can't access other classes in GML, as they don't exist.
As was pointed out, the "basic" is to have all you can as private, and use public getter and setters.
A getter and a setter don't even have to have the same scope (i.e. you can have a public getter, and a private setter, which is very good)
 

kburkhart84

Firehammer Games
The neat part about getters/setters that I don't think anybody mentioned, is that they can contain code. For sure, that code should set/get the value in question, but it can also do about anything else you want it to. It could access min/max variables to make sure the value being set is in the range, for example(a common use). But since it is code, it can do whatever you want really. GML can pretty much do the same thing with structs and method variables on instances...just that they aren't really like getters/setters, rather they would just be other functions you create that happen to serve that purpose. The difference is that it isn't going to be able to use the '=' assignment operator to do it like in C#, rather it would be invoked just like any other function would.
 
The neat part about getters/setters that I don't think anybody mentioned, is that they can contain code. For sure, that code should set/get the value in question, but it can also do about anything else you want it to. It could access min/max variables to make sure the value being set is in the range, for example(a common use). But since it is code, it can do whatever you want really. GML can pretty much do the same thing with structs and method variables on instances...just that they aren't really like getters/setters, rather they would just be other functions you create that happen to serve that purpose. The difference is that it isn't going to be able to use the '=' assignment operator to do it like in C#, rather it would be invoked just like any other function would.
Absolutely. The only solid rules for them are:
For set: - An implicit value parameter named value, of the same type as the property and a return type of void
For get: - No parameters and a return type of the same type as the property

I will mention to the OP that if you do research on this, these are called PROPRIETIES (when you have getter and setter), it's not a Field, by that point (i.e. a simple regular variable).
Altough from their usage, there is no way to tell them apart that I know of:
C#:
SomeClass someName = new SomeClass();
someName.MyField = 5;         // Assigning to a field
someName.MyProperty = 10;     // Assigning to a property, the compiler knows to use either the get or set method depending on the assignment, it's quite magic
It may take a bit to get used to it, but C# is really cool. Probably my favorite language to code in, you can do many cool things with it and .NET.
You have quite a bit of low-level power while still not having to really care about memory management (C# is garbage-collected, as opposite to C++). Access to pointers (which is awesome when you want to upgrade from GMS and go in the big leagues), data types, and many things you'll have to learn, but it's all good fun and there's a ton of resources online (Microsoft official tutorials are good)...Hang in there, you'll be glad you did!
 
Last edited:
Top