Прелесть DataContracts (а иногда и их проклятие) в том, что VS может создать объект, который будет выполнять DataContract, без необходимости делать вашу реализацию публичной. Итак, если вы не хотите отправлять DLL, хорошо; когда потребители вашей службы добавляют ссылку на службу, VS создает свой собственный объект TestResults, который реализует ITestResults и определяет средства доступа для DataMembers.
Обратите внимание, что из-за этого поведения лучше всего делать реализации DataContract "анемичными"; вы не можете определить бизнес-логику, которая будет передавать сгенерированную реализацию, поэтому лучше всего настроить их как содержащие только поля или простые свойства. Таким образом, ваш сервис не может делать никаких предположений о том, что любой сгенерированный класс сможет сделать с другой стороны.
РЕДАКТИРОВАТЬ: Если класс или интерфейс, который является ServiceContract, предоставляет метод, который возвращает TestResult как OperationContract, тогда TestResult ДОЛЖЕН быть DataContract, а любые интересующие его свойства или поля должны быть DataMembers. Это не лучшая практика, это обязательно нужно. С другой стороны, независимо от видимости метода в коде на стороне сервера, если метод не является OperationContract, то он невидим для клиента, и TestResult не обязательно должен быть DataContract, ЕСЛИ МЕНЬШЕ другой метод OperationContract принимает или возвращает экземпляр TestResult.
Вы заявили, что возвращаете TestResult в результате вызова службы. На самом деле это звучит так: ваш OperationContract возвращает класс DataContract, который выглядит как TestResult, а вы возвращаете TestResult. Это указывает на то, что существует неявное преобразование, указанное между TestResult и TestResultDataContract, или некоторое поведение на более высоком уровне, которое клонирует TestResult в TestResultDataContract. Все в порядке; преобразование происходит перед возвратом, а DataContract по-прежнему является тем, что фактически выходит из метода обслуживания. Вы можете задокументировать, что происходит, если вы возвращаете TestResult из метода, указывающего, что он возвращает тип TestResultDataContract.
Другая возможность заключается в том, что вы на самом деле не вызываете службу как удаленную службу WCF через сгенерированный клиентский прокси; вы просто создаете экземпляр и вызываете класс, который фактически реализует сервис. Я видел это много раз; все, что требуется, это ссылка на класс реализации, а не на прокси-сервер, и передать привет ошибкам в производственной среде, которых вы не видели в dev. При условии, что вы ДЕЙСТВИТЕЛЬНО ИСПОЛЬЗУЕТЕ клиентский прокси, совершенно нормально ссылаться на ту же реализацию TestResult (или его брата, украшенного DataContract) в клиентском коде, если у вас есть доступ к DLL, содержащей этот контракт на клиенте. Однако весь смысл в том, что в этом нет необходимости; если у вас нет объекта, соответствующего подписи DataContract службы, он будет создан для вас.