Как в c# правильно написать такой алгоритм?
В общем случае никак. Конечно можно соорудить примерно такой зоопарк:void tries(params Func<Void> bodies) {
	try {
		bodies[0]();
	} catch {
		tries(bodies.Skip(1).ToArray());
	}
}

// using
tries( () => {
		// first try
	}, () => {
		// second try if first failed
	}, () => {
		// third try if second after first failed
	} ... )
Но @gleb_kudr и остальные правы - исключения далеко не лучший способ построения архитектуры приложения и уж точно он не должен быть использован для реализации алгоритма. Хотя исключения сегодня достаточно дёшевы (в C# по мелкомягкой политики мы и так платим за исключения даже не используя их), но алгоритм логичнее делать именно с помощью ветвлений, а не обработок исключений. Единственный use-case который я смог придумать - большое количество различных "одинаковых" ресурсов с различной степенью актуальностью - от сети до просьбы вставить диск. Как-то так. Но всё таки это экзотические ситуации и следует понимать, что исключения - всё таки исключительные ситуации и требоваться они должны редко. Если программа успешно (идеально) отработало, но было брошено сотни исключений - дело плохо.
Если вы можете убрать эти exception, то может, действительно, переделать на if else?if(method1()) {}
else if (method2()) {}
else if (method3()) {}
else {
    // выполняется при неудаче во всех случаях
}
а в методах method1, method2, method3, ... уже реализуете ваши варианты, и они возвращяют boolean