Привет, существует множество инструментов для обфускации кода .NET, которые усложняют декомпиляцию и делают код менее понятным. Они меняют имена переменных, методы и классы на случайные имена, добавляют искусственные конструкции и т.д. Это помогает, но не обеспечивает абсолютной защиты.
Так же вы можете использовать Native Compiler: .NET Framework и .NET Core (а нынче и .NET) поддерживают компиляцию в машинный код. Это происходит на стадии выполнения (Just-In-Time, JIT) в большинстве случаев, но существуют способы явно перекомпилировать или сгенерировать исполняемый файл в машинном коде. Это значительно сложнее для декомпиляции.