Is C# easier to learn than C++?

Classes

Already know how to define.

Constructors

They are kind of functions for classes to allow instantiation. You can also pass parameters through them. And if you don’t create them, the program will.

class Zoom // haha get it, Zoom calls
{
    ...
    public Zoom()
    {
        ...
    }
}

To call them…

Zoom z = new Zoom(); // surprise!

Destructors

The opposite of constructors, they clear out the memory by deleting objects at the end of the program.

~Zoom()
{
    code;
}

They aren’t inherited, by the way.


New source!

https://www.w3schools.com/cs/

Properties

Allow to access private data outside their class with get and set.

class Animal
{
    private string genus;

    public string Genus
    {
    get {return genus;}
    set {genus = value;}
    }
}

class Program
{
    static void Main(string[] args)
    {
    Animal d0g = new Animal();
    d0g.Genus = "Canis";
    }
}

What’s the point of using shorthand get and set if you don’t even have private data declared? It’s shorter and it automatically creates the private field.

public string Genus {get; set;}

Inheritance

Also based on tutorialspoint but whatever
class Mammal
{
    code;
}

class D0g : Mammal
{
    code;
}

They inherit methods, variables and stuff.

Use the “sealed” keyword to prevent inheritance.

sealed class Liger // haha get it they are sterile
{
    code;
}

Polymorphism

class Animal
{
    public virtual void Sound()
    {
        code;
    }
}

class D0g : Animal
{
    public override void Sound()
    {
        code;
    }
}

Without virtual and override, both methods would give the same output.

It automatically makes the backing field. So it saves you on typing. Your animal example could also be written like this, which is much shorter and faster to read and understand for other programmers:

class Animal
{
   public string Genus { get; set; }
}

But if there is no private field, then why? Does it create one implicitly?

Yes, that’s what I’m trying to say with “It automatically makes the backing field”.

1 Like

Ah, I guess I didn’t understand what backing meant. Sorry. Gonna continue tutorial shortly.

Ha! Finished the tutorials!

Abstraction

Hides details apparently. Shows only what the user needs to know. What does that mean? Example?

Two ways:

  • Abstract classes
  • Interfaces

Abstract classes have rules:

  • Can’t be used to create objects directly. It must have a derived class.
  • It has abstract methods too.

Ok.

abstract class Animal
{
    public abstract void Sound(); // never have a body
}
class D0g : Animal
{
    public override void Sound()
    {
        Console.WriteLine("Woof!");
    }
}

Interfaces

Just like abstract classes except that they can’t have fields. Only methods and properties. By default, they are abstract and public. They also allow multiple inheritance.

interface IAnimal
{
    void Sound();
}

interface ILife
{
    void Reproduce();
}

class D0g : IAnimal, ILife
{
    public void Sound()
    {
        Console.WriteLine("Woof!");
    }

    public void Reproduce()
    {
        Console.WriteLine("Dog has reproduced.");
    }
}

Files

Manipulate files with the File class from the Sytem.IO namespace. For instance…

using Sytem.IO;

string writeText = "Over here, Jimmy!";
File.WriteAllText("distraction.txt", writeText);

string readText = File.ReadAllText("distraction.txt");
Console.WriteLine(readText);

/* Outputs "Over here, Jimmy!" */

Exceptions

try: test for errors
catch: handles them
finally: final output or result

try
{
    double[] arr = new double[] {2.05, 3.1416};
    Console.WriteLine(arr[3]);
}
catch(Exception e)
{
    Console.WriteLine(e.Message);
}
finally
{
    Console.WriteLine("End of log.");
}

/* Outputs "Index was outside the bounds of the array.
End of log." */

To create custom errors, use throw.

if(age<13)
{
    throw new ArithmeticException("You can't subscribe to Steam!");
}
else
{
    Console.WriteLine("Please create your Steam account.");
}

I’m done! YES!

What now? I guess I’ll upgrade my calculator by replacing the doubles with nullables and try to create a log of errors. After that, I might create a small text editor with passwords and possibly very simple encryption methods. Finally, I might try to analyze one of Thrive’s files.

Abstract classes has nothing to do with abstractions.

Abstraction means that you build on top of other parts of your program. For example you can write a class to execute SQL commands on a database, then you can write a method for saving a user.
After that everywhere in your program you can just call the user saving method without having to know anything about what it does internally.
This means that with the right abstractions you can work on bigger systems as, without abstractions you couldn’t hold the entire program in your head, so you would make a ton of mistakes / need to constantly refer to other parts of your program. And that’s not good. That’s why abstraction is one of the most important parts in big programs: make reusable parts, that have simple to understand interfaces that other parts of the program can use.

Interfaces aren’t classes at all. They are just specifications that “all classes that implement this interface, promise to implement these properties and methods”.

Go for it.

1 Like

Ah, shiiit.

I started updating it, but it gave me a few errors. I thought that maybe my C# compiler is just outdated and that I should use VS instead to get the new compiler. I saw this tutorial :

So I went for it and merged my code with the structure suggested in this tutorial, but it just made things more complicated. Is there any way to use C# 9.0 without VS? Like using cmd for compiling upper versions?

You can check this out:
https://jrliv.com/post/get-started-using-csharp-without-visual-studio/

but it is easier to use visual studio to compile it

Too complicated to use. Especially for how “simple” the program really is. If it was a video game, then I might consider using an IDE.

This is exactly the same version! Framework is apparently outdated.

aaaaaaaaaah

The problem with the Microsoft Calculator tutorial is that they want you to work the way they do. At this point, they should just give the code right away and make you learn about the interface of VS instead.

You know what? Unlike last time, I think that when I tried to update my calculator I didn’t have a proper plan at hand. I’ll revert back to original code and give out how I made the nullables work instead. Tomorrow, I’ll learn more about VS first, then try to remake the code in it with a good plan in my head.

UPDATE

This is how nullables work!

Calculator
program.cs
using System;

namespace Calculator
{
	class Program
	{	
		static void Main(string[] args)
		{	
			double? num1, num2;
			num1 = null;
			num2 = null;
			
			while(true)
			{
				Console.WriteLine("This is a calculator. Type 'list' to see all possible operations.");
				string choice = Console.ReadLine();
				
				switch(choice)
				{
					case "1":
						
						Console.WriteLine("You have chosen 'Addition'.\nPlease enter the first number if necessary...");
						/*The user has to enter the numbers first, then the code will take care of the operation.
						If the user has not cleared the previous result, they won't have to enter the first number.*/
						
						Arithmetics addition = new Arithmetics();
						num1 = num1 ?? Convert.ToDouble(Console.ReadLine()); // if num1 has been cleared, enter the number. Otherwise, keep the same value.
						
						Console.WriteLine("Now, please enter the second number...");
						num2 = Convert.ToDouble(Console.ReadLine());
						
						addition.Addition((double) num1, (double) num2);
						Console.WriteLine("The result is {0}", addition.result);
						num1 = addition.result;
						
						continue;
					
					case "2":
					
						Console.WriteLine("You have chosen 'Subtraction'.\nPlease enter the first number if necessary...");
						
						Arithmetics subtraction = new Arithmetics();
						num1 = num1 ?? Convert.ToDouble(Console.ReadLine());
						
						Console.WriteLine("Now, please enter the second number...");
						num2 = Convert.ToDouble(Console.ReadLine());
						
						subtraction.Subtraction((double) num1, (double) num2);
						Console.WriteLine("The result is {0}", subtraction.result);
						num1 = subtraction.result;
						
						continue;
					
					case "3":
					
						Console.WriteLine("You have chosen 'Multiplication'.\nPlease enter the first number if necessary...");
						
						Arithmetics multiplication = new Arithmetics();
						num1 = num1 ?? Convert.ToDouble(Console.ReadLine());
						
						Console.WriteLine("Now, please enter the second number...");
						num2 = Convert.ToDouble(Console.ReadLine());
						
						multiplication.Multiplication((double) num1, (double) num2);
						Console.WriteLine("The result is {0}", multiplication.result);
						num1 = multiplication.result;
						
						continue;
					
					case "4":
					
						Console.WriteLine("You have chosen 'Division'.\nPlease enter the first number if necessary...");
						
						Arithmetics division = new Arithmetics();
						num1 = num1 ?? Convert.ToDouble(Console.ReadLine());
						
						Console.WriteLine("Now, please enter the second number...");
						num2 = Convert.ToDouble(Console.ReadLine());
						
						division.Division((double) num1, (double) num2);
						Console.WriteLine("The result is {0}", division.result);
						num1 = division.result;
						
						continue;
					
					case "5":
					
						Console.WriteLine("You have chosen 'Modulus'.\nPlease enter the first number if necessary...");
						
						Arithmetics modulus = new Arithmetics();
						num1 = num1 ?? Convert.ToDouble(Console.ReadLine());
						
						Console.WriteLine("Now, please enter the second number...");
						num2 = Convert.ToDouble(Console.ReadLine());
						
						modulus.Modulus((double) num1, (double) num2);
						Console.WriteLine("The result is {0}", modulus.result);
						num1 = modulus.result;
						
						continue;
					
					case "list":
						Console.WriteLine(" 1-Addition \n 2-Subtraction \n 3-Multiplication \n 4-Division \n 5-Modulus: Find the remainder of a division. \n clear-Clear the previous result. \n exit-Exit the program.");
						continue;
					
					case "clear":
						num1 = null;
						Console.WriteLine("The result has been cleared.");
						continue;
					
					case "exit":
						Console.WriteLine("Please press <Enter> to exit...");
						Console.ReadKey();
						break;
					
					default:
						Console.WriteLine("Wrong input. Please enter a valid input.");
						continue;
				}
				break;
			}
		}
	}
}
arithmetics.cs
using System;

namespace Calculator
{
	class Arithmetics
	{
		public double result;
		
		public double Addition(double number1, double number2)
		{
			result = number1 + number2;
			return result;
		}
		
		public double Subtraction(double number1, double number2)
		{
			result = number1 - number2;
			return result;
		}
		
		public double Multiplication(double number1, double number2)
		{
			result = number1 * number2;
			return result;
		}
		
		public double Division(double number1, double number2)
		{
			result = number1 / number2;
			return result;
		}
		
		public double Modulus(double number1, double number2)
		{
			result = number1 % number2;
			return result;
		}
	}
}

I generally draw some flowchart to get a good plan in my head. The problem is that my notions of flowchart are a bit limited (e.g. I don’t know what symbol to use for classes or interfaces). Do you guys have any advice concerning flowcharts or planning?

I have the opposite opinion, an IDE helps especially when you are starting. I started learning programming and C++ with Visual Studio. And it was very helpful that it would show me errors in real time when I was typing so I could easily see when I made mistakes. Also the debugger was super helpful, it is so good to be able to put a breakpoint on any line, run your program, and then inspect all the variables to see what’s wrong. Quite often I see programmers struggling with an issue that could be solved in a couple of minutes if only they used a few breakpoints to inspect where their assumptions about their program turn out to be incorrect.

Flow charts (or any kind of drawing beyond very simple stuff) is not really used in industry. The only place flowcharts are really done are schools. In real programming work they aren’t used, except in very rare cases to communicate some specific information to others, though pseudocode is probably more popular in that use case.

Ah, finally.

Here’s the new one with VS.

2 Likes

Looks like you included the compiled binaries in git, which is something that should be always avoided. It’s a pretty classical new git user mistake to make, so you might want to look at git tutorials as well (especially how to setup a .gitignore properly).

2 Likes

@Evolution4Weak, why did you fork my calculator? There’s nothing wrong about it, but I’m just curious to see why you forked my program.

I might give a GitHub this evening for my text editor or at least what’s done.

After the text editor, I might do some small edits on my calculator and experiments with arrays and graphics. Possibly trying to make a kind of small procedural map with ASCII characters and arrays.

Finally, I’m going to create some small 2D games with Godot Mono such as:

  • Pong clone
  • Snake clone
  • Small platformer (at least a prototype)
  • Small RPG (at least a prototype)

After that, I might try to recreate Thrive’s Microbe stage in 2D, which should take probably months at most.

After working with 2D games, I’ll try to see how 3D works in Godot. Maybe make an FPS prototype. Given that Godot is not that advanced in 3D or so I might think, I’ll probably learn Lua to make a custom gamemode in Garry’s Mod, that is if S&Box doesn’t come out (it’s in C#). I’ll have to learn Lua anyway if I want to start modding HL: Alyx, which has its scripts based on some kind of Lua language. That will give me enough experience with VR and…

Ah! All of this is too far in the future! I should stop dreaming.

Here’s my text editor or rather what’s done.

I needed to fork it to make a pull-request

do you use the command line for github?

Eh, nope. I’m too much of a noob with GitHub. I might learn more about it tomorrow.

A pull-request for what btw?

I made a pull-request to add a git-ignore and a readme, nothing too much

if you want a visual way to use git, you could use something like https://www.sourcetreeapp.com/

1 Like

I’ll answer shortly to your pull request. Please stand by.

Done. Pull request merged.

Didn’t have time to learn git. Needed time with family, you see.

Reviewing Thrive/MicrobeColony.cs…

using System;
using System.Collections.Generic;	// What is this?
using System.Linq;			        // What is this?
using Newtonsoft.Json;			/* Reminds me of something, but what is this? Is it some kind of NuGet Package, which I also don't know what that is? */

[JsonObject(IsReference = true)]	// https://youtu.be/FNIeQDP37Nc
public class MicrobeColony		    // Seems good, it respects the name of the file...
{
    private Microbe.MicrobeState state;	// https://youtu.be/FNIeQDP37Nc ? Microbe.MicrobeState?

    public MicrobeColony(Microbe master)	// Constructor, so Microbe is a class? Ok...
    {
        Master = master;
        master.ColonyChildren = new List<Microbe>();	// What is a list? Some kind of dynamic array perhaps?
        ColonyMembers = new List<Microbe> { master };	// Ok, so a list is a collection of objects for a said class?
        /* Why would the colony members follow a master? A multicellular colony, AFAIK, doesn't have a master. All cells are equally important. Or maybe it's because you need to know which cell is attached to the master or another? */
	    ColonyCompounds = new ColonyCompoundBag(this);	// Seems to be some kind of collection for all compounds within a colony...
    }

    [JsonProperty]
    public List<Microbe> ColonyMembers { get; private set; }	// So you can have a private part in a property? Nice.

    [JsonProperty]
    public ColonyCompoundBag ColonyCompounds { get; set; }	// Why setting a property if it is public?

    [JsonProperty]
    public Microbe.MicrobeState State
    {
        get => state;
        set
        {
            if (state == value)
                return;

            state = value;
            foreach (var cell in ColonyMembers)	// var keyword? In C#? I thought it was in JS.
                cell.State = value;		// Okay, so the other cells in colony can be modified.
        }
    }

    [JsonProperty]
    public Microbe Master { get; set; }

    public void Process(float delta)
    {
        _ = delta; // Disable parameter not used suggestion
	    /* What the hell is delta? And why using a single underscore as an identifier? */
        ColonyCompounds.DistributeCompoundSurplus();	// So the colony gets the surplus compounds from certain cells and distributes them.
    }

    public void RemoveFromColony(Microbe microbe)
    {
        if (microbe?.Colony == null)
            throw new ArgumentException("Microbe null or invalid"); // custom error. Ok. But what is this part for?

        if (!Equals(microbe.Colony, this))	// What does this mean? haha get it? cuz what does 'THIS' mean
            throw new ArgumentException("Cannot remove a colony member who isn't a member");

        ColonyMembers.ForEach(m => m.OnColonyMemberRemoved(microbe)); // what is '=>' operator? And why is foreach a method? I'm confused. Need more research.
	    /* Ok, maybe it's to iterate through the colony members? */
        ColonyMembers.Remove(microbe);

        while (microbe.ColonyChildren.Any())
            RemoveFromColony(microbe.ColonyChildren[0]);

        microbe.ColonyParent?.ColonyChildren?.Remove(microbe);

        microbe.Colony = null;
        microbe.ColonyParent = null;
        microbe.ColonyChildren = null;

        if (State == Microbe.MicrobeState.Unbinding)	// Why is there no bracket?
            State = Microbe.MicrobeState.Normal;
    }

    public void AddToColony(Microbe microbe, Microbe master)
    {
        if (microbe == null || master == null || microbe.Colony != null)
            throw new ArgumentException("Microbe or master null");

        ColonyMembers.Add(microbe);

        microbe.ColonyParent = master;		// Ok, so the microbe it is attached to (parent) becomes their master.
        master.ColonyChildren.Add(microbe);	// then the master adds the new cell to the colony
        microbe.Colony = this;			// https://youtu.be/O5BJVO3PDeQ?t=632
        microbe.ColonyChildren = new List<Microbe>();
	    /* Why not making the whole colony a single list? Is that what the debate between hhyrylainen and FuJa was about? */
        ColonyMembers.ForEach(m => m.OnColonyMemberAdded(microbe));
    }
}

List and Dictionary are defined there.

It defines SQL-like collection operators, for example you can filter a list by condition after including it: myList.Where(item => item.SomeCondition)

Nuget is a package manager for C#, it’s like pip for python and gems for ruby. It helps you easily to install code libraries. It’s much easier to use than going on github and cloning or downloading some repositories and then including those in your project.
As the name of that package implies, it is for JSON operations.

When this class is saved (serialized to JSON), it’s used as a reference, supporting including the same object multiple times in the save without duplicate instances. Also, you’ve seen nothing yet:

[JsonObject(IsReference = true)]
[JSONAlwaysDynamicType]
[SceneLoadedClass("res://src/microbe_stage/Microbe.tscn", UsesEarlyResolve = false)]
[DeserializedCallbackTarget]
public class Microbe : RigidBody, ISpawned, IProcessable, IMicrobeAI, ISaveLoadedTracked

It’s a nested enum, defined inside a class. So it needs to be referred to by using the class name as a prefix.

The colony is a single game entity. All of the microbes are reparented as child scenes of the master. So only the master Microbe exists directly in the game scene.

It’s probably a mistake, it’s probably meant that the set would be private. When you make multiple hundred lines of changes, there’s bound to be mistakes in it as it’s written by a human.

It automatically determines the type of the variable. Very useful, and very widely used in Thrive. Similar to auto in C++, which I also use a lot. Code looks way too much like overtly verbose, bloated, Java, if you don’t use var.

The CI (continuous integration) checks will not let your PR pass if it has a unused method parameter. C# has special syntax _ = something to mark that it is intentional that something is not used to make the checks pass.

Delta is the time since last frame, which is currently bugged in Godot, because someone thought that negative time between frames was a good idea…

It’s good to check assumptions at the start of a method and throw custom exceptions, that way it is much easier to find problems, than if you get a random NullReferenceException from a method called 3 levels deep.

In a method this refers to the current object on which the method was called.

It’s a lambda function (an inline function without a name). And it makes a lot of code much cleaner.

LINQ

Single line if bodies work without it. The Thrive styleguide says they can be omitted here, to make the code shorter.


I don’t know why I spent so long on this post…

2 Likes

I updated my text editor library.

If I ever implement editing other types of file, they will have their own class, which should inherit from the TextFile class. Only the IsRightType() method should be overriden in that case. Now, I just need to find a way to both read the contents of a file and write as I please (multiple lines).

@hhyyrylainen, from all the notions I’ve shared, is there anything missing that could be useful for the issues I just mentioned?

What issues did you mention? I didn’t notice any issues in the upper paragraph, because you already showed code doing file read and write, so that shouldn’t be a problem. If I’d comment on anything I’d say it is pretty weird that you would use TextFile as a base class because it doesn’t make sense that a more specialized type of TextFile would handle binary files for example. Instead you should have a more generally named base class something like File.

1 Like