Вот несколько предложений. Я не собираюсь рекомендовать какое-то окончательное состояние, но лишь несколько вещей, которые помогут.
Я подхожу к «оптимизации» с точки зрения упрощения чтения и обслуживания кода. В этом коде нет ничего, что могло бы заставить меня задуматься о том, как быстро он работает
Вы начинаете с этого:
if (message.GetType() == typeof(string))
// code to print the string
if (message.GetType() == typeof(SomethingElse))
// code to print SomethingElse
Первым шагом было бы поместить код для каждого типа вещи, которую вы хотите напечатать, в свой собственный метод, чтобы теперь он выглядел следующим образом.
if (message.GetType() == typeof(string))
PrintString((string)message);
if (message.GetType() == typeof(SomethingElse))
PrintSomethingElse((SomethingElse)message);
Это небольшой рефакторинг. Все это делает его перемещением кода в отдельные методы. Теперь у вас есть один метод, который берет message
и определяет, какой метод использовать для его печати. Тогда у вас есть отдельные, меньшие методы, каждый из которых отвечает за печать только одного типа. Это просто облегчает чтение всего этого.
Что еще лучше, если нам не нужно проверять и аргументировать, чтобы увидеть, какой это тип. Код за пределами PrintExample<T>
уже знает, какой тип он будет передавать методу. Он звонит PrintExample<string>()
, PrintExample<SomethingElse>()
и т. Д.
Так что нет никакой причины иметь один метод, который может принимать аргументы любого типа, вызывать его, а затем возвращаться к попытке выяснить, к какому типу он относится.
Вместо этого, учитывая, что ваш код будет знать, как печатать конечное число вещей, вы можете просто написать метод для каждого из них и сделать их общедоступными:
public void Print(string value)
public void Print(SomethingElse value)
С этим еще проще работать. Общий метод позволяет вам вызывать
PrintExample<ThisCouldBeAnything>(thing);
Но что, если ThisCouldBeAnything
на самом деле не является типом, который метод может печатать? Если у вас есть разные методы для разных типов, тогда, если у вас есть переменная определенного типа, действительно легко увидеть, существует ли метод для ее печати. Также легко вызвать правильный метод.
Следующим шагом является поиск кода, который повторяется, и помещение его в отдельные методы или даже в отдельные классы.
Если методы печати List<Something>
и Dictionary<int, Something>
оба должны печатать детали Something
, вы можете иметь один PrintSomething
метод, который оба они вызывают.
Вот еще кое-что, что нужно учитывать: вы создаете методы, которые принимают разные вещи и пишут строки, которые их описывают. Как есть, ваш класс может писать только в файл. Что если вы хотите большую часть этой функциональности, но не хотите записывать в файл? Что, если вы хотите записать это на консоль или сделать что-то еще с ней?
Может быть, лучше поместить их в отдельный класс или классы, чтобы методы возвращали string
или передавали StreamWriter
методу или классу. Таким образом, если класс хочет что-то записать в файл, этот класс может использовать класс «Printer» или классы для этого. Но если другой класс хочет сделать что-то еще с выходными данными, он может это сделать.
Это становится еще более важным, если вы хотите писать модульные тесты. Лучше разбить занятия на отдельные обязанности. Один отвечает за преобразование SomeClass
в строковый вывод, и вы можете проверить, правильно ли он это делает, сравнив строку с тем, что вы ожидаете. Это было бы сложнее, если бы для проверки вам пришлось записать файл, а затем открыть файл и прочитать его.