Skip to content

Enums, files and exceptions

↑

Examples are independent C# snippets for modern .NET console projects unless noted otherwise. Class declarations and top-level code can live in Program.cs when top-level statements come first.

Enums give meaningful names to a fixed set of numeric values. Files involve external state that can fail; exceptions communicate exceptional failures.

An enum is a named value type with an underlying integral representation. Prefer it to unrelated magic integers for a fixed group of options. An enum variable can still contain an unnamed numeric value, so validate untrusted input.

Example.cs
GameState state = GameState.Playing;
if (state == GameState.Playing)
Console.WriteLine("Game running");
enum GameState { Menu, Playing, Paused }

File.WriteAllText and File.ReadAllText are convenient for small text files. Use a path appropriate for the environment, and consider encoding, permissions and file size. For Unity save data, choose a writable persistent-data path rather than application installation folders.

Example.cs
using System.IO;
string path = Path.Combine(Path.GetTempPath(), "hcstech-example.txt");
File.WriteAllText(path, "Hello file");
Console.WriteLine(File.ReadAllText(path));
File.Delete(path);

Catch only exceptions you can meaningfully handle. Use finally to run cleanup whether an exception occurs or not, and using for disposable resources. Avoid swallowing all errors silently.

Example.cs
using System.IO;
try
{
string text = File.ReadAllText("missing-file.txt");
Console.WriteLine(text);
}
catch (FileNotFoundException)
{
Console.WriteLine("No saved data found.");
}
finally
{
Console.WriteLine("Read attempt finished.");
}

Deep dive: represent states, handle resources, and recover deliberately

Section titled “Deep dive: represent states, handle resources, and recover deliberately”

Enums improve meaning, not input validation

Section titled “Enums improve meaning, not input validation”

An enum gives names to a set of integral constants, making code such as GameState.Paused easier to read than a mysterious number. By default, an enum uses int, and any representable underlying integer can be cast to it, even if you did not declare a matching member. Validate external input using Enum.IsDefined or an explicit mapping rather than assuming every value is recognized.

Paths may not exist, access can be denied, and a disk may be full. File.ReadAllText and File.WriteAllText are convenient for small files, but larger files benefit from streams and asynchronous I/O. Never treat untrusted filenames as safe path components without validation. In Unity, choose appropriate writable directories such as Application.persistentDataPath rather than trying to modify packaged assets in a build.

Program.cs
using System.IO;
string path = Path.Combine(Path.GetTempPath(), "hcstech-example.txt");
try
{
File.WriteAllText(path, "Saved");
Console.WriteLine(File.ReadAllText(path));
}
catch (IOException ex)
{
Console.Error.WriteLine($"Storage failed: {ex.Message}");
}

Exceptions describe failures outside normal results

Section titled “Exceptions describe failures outside normal results”

Use exceptions for exceptional failures such as inaccessible storage or violated method contracts, not as a routine substitute for validating every expected player input. Catch a specific exception where you can recover or add meaningful context. throw; inside catch preserves the original stack trace; throw ex; resets important stack information. finally runs whether control exits normally or through an exception, and using/await using normally makes disposal clearer for disposable resources.

An empty catch can make corrupted data look like a successful save. If an error cannot be handled locally, let it propagate or wrap it with useful context while preserving the original as an inner exception. Report failures in a way appropriate to the application; never display secrets or internal filesystem paths to untrusted users.

Use enums for named modes, files for persistent data and precise exception handling where external operations can fail.

Do not assume a file exists or a write succeeds. Prefer throw; rather than throw ex; when rethrowing the current exception to preserve its original stack trace.

Model a game state as an enum and handle a missing save file without crashing.

Reveal a solution

Use enum GameState and catch FileNotFoundException around the read.