Skip to content

C# Tips

Valk edited this page Apr 22, 2025 · 7 revisions

Do not concern yourself with the object count

{9FEADB64-EA6E-410D-9963-8A24E456AC03}

Objects are not cleaned up immediately after they are used and there is nothing you can do about this because this is just how C# garbage collector works. This is normal intended behavior. Just stop looking at the object counter in the Debugger > Monitors. Everything is fine here. Instead why don't you monitor the node count, yeah now that's something you should monitor!

This page will not directly talk about SRP, SoC, YAGNI principles. Although I highly encourage you to look up what these are.

You need to return more than one member, what do you do?

There are 2 ways to approach this.

  1. Create a new class that holds the members
  2. Add out params as needed for the additional members

If you don't want to create a whole new class the latter may be what you are looking for.

Explicit Event Args

You may have something like public event Action<int, int, int> OnPlayerUpdate. There are a few things wrong with this.

  1. Assuming this is defined in player class this should not need to have "Player" defined in its name.
  2. The single responsibility principle (SRP) is being violated. There should be separate events like OnHealthChanged<int> and OnPositionChanged<Vector2>.
  3. But the biggest problem is the event args are implicit. You have no idea what they mean on the subscribers end. If we ignore SRP, we will need to create a PlayerUpdateEventArgs class with a primary constructor containing all the event args as public properties. Then we can pass this class as a single param and our subscriber will know what's what.

Avoid Wall of Text

Too much text together can blind your eyes.

Before

ItemContainer targetItemContainer = otherInventoryContainer.ItemContainers[otherIndex];
TransferEventArgs args = new(areSameType, index, targetItemContainer);
OnPreTransfer?.Invoke(args);

After

ItemContainer targetItemContainer = otherInventoryContainer.ItemContainers[otherIndex];

TransferEventArgs args = new(areSameType, index, targetItemContainer);

OnPreTransfer?.Invoke(args);

Avoid Lots of Method Params

Create context classes and pass these classes as params to avoid adding too many params to methods.

public class InventoryVFXContext(CanvasLayer ui, ItemContainer[] itemContainers, Inventory inventory)
{
    public CanvasLayer UI { get; } = ui;
    public InventoryVFX VFX { get; } = new();
    public ItemContainer[] ItemContainers { get; } = itemContainers;
    public CursorItemContainer CursorItemContainer { get; } = Services.Get<CursorItemContainer>();
    public Inventory Inventory { get; } = inventory;
    public Inventory CursorInventory { get; } = Services.Get<CursorItemContainer>().Inventory;
}
public void RegisterInput(InventoryContainer container, InventoryVFXContext context)
{
    Inventory inventory = context.Inventory;
    Inventory cursorInventory = context.CursorInventory;
    
    // ...
}
Clone this wiki locally