Нет никакого "лучше". Есть только то, для чего они предназначены и об этом подробно говорится в
документации.
0. Каждый из этих модификаторов имеет разные смыслы в зависимости от контекста.
1. ref struct - запрещает боксить структуру и вообще как-либо иначе заносить в кучу.
2. in (в женериках) - обозначает, что параметр контрвариантный (загугли)
3. out (в женериках) - обозначает, что параметр инвариантный (тоже загугли)
4. in/ref/out как модификатор аргументов методов - указывают, что передаваться будет ссылка (например на переменную).
in - запрещает модификацию. out - обязывает инициализировать перед завершением метода. ref - никчему не обязывает.
Из очевидных, но не ограничивающих сценариев использования (п4):
1. in - для передачи больших структур, чтобы они не копировались.
2. out - для
TryParse
3. ref - для
Swap
4. Ещё их всех можно использовать в P/Invoke для того же самого. Всякие нативные методы достаточно часто работают со ссылками.