Невозможно определить тип из того, что я вижу, что вы делаете, вы пишете что-то вроде этого:
MyCode|MyDescription|MyPrice|MyAdditionalProperty
Невозможно определить тип по этой строке, если к свойствам унаследованных классов не наложены дополнительные правила.
Что вы можете сделать, это добавить эту информацию в качестве первого элемента:
textOut.Write(product.GetType() + "|"); // You can write a switch instead to write your own string instead of a full name
Затем, когда вы читаете свои данные, вы сначала читаете моникер типа, после этого вы пишете переключатель для создания экземпляра вашего класса или используете отражение, если вы пишете полный тип.
P.S. Я бы посоветовал заглянуть в некоторые стандартизированные библиотеки (или встроенные методы), чтобы выполнить сериализацию / десериализацию вместо того, чтобы писать ее самостоятельно, если только у вас нет для этого веской причины.