Как и в случае любой удаленной архитектуры, вам следует избегать неконтролируемой загрузки полного графа объектов "по проводам" (если только у вас нет тривиально небольшого числа объектов).
В статье Википедии стандартные методы в значительной степени обобщены (и в C #. Тоже!). Я использовал и призраков, и держателей ценностей, и они работают довольно хорошо.
Чтобы реализовать этот вид техники, убедитесь, что вы строго разделяете проблемы. На сервере классы реализации вашего контракта на обслуживание должны быть единственными частями кода, которые работают с контрактами на данные. На клиентском уровне доступ к сервису должен быть единственным кодом, который работает с прокси.
Подобные уровни позволяют вам настроить способ реализации службы относительно независимо от уровней пользовательского интерфейса, вызывающих службу, и бизнес-уровня, который вызывается. Это также дает вам половину шансов на юнит-тестирование!