У вас неправильное впечатление - DataContract, который предоставляет сервер, может (и должен) только содержать данные - никогда никакого поведения. Таким образом, вы можете никогда обмениваться объектами между клиентом и хостом - все, что вы можете поделиться - это сервисные методы для вызова и конкретные типы для использования в этих методах. Вот и все.
Процесс таков: когда клиент подключается к серверу, он загружает метаданные для службы - он может узнать, какие методы службы доступны, какие данные они принимают - но он не может сделать вывод о любых дополнительных методах на основе данных контракта. Это просто не может. Затем клиент создает точную копию типа контракта данных - но это совершенно отдельный класс, и он соответствует только классу контракта данных на стороне сервера, если речь идет о его сериализованном представлении в XML. Это не того же класса - он просто выглядит одинаково.
Потому что, в конце концов, все, что происходит между сервером и клиентом, это обмен сериализованным сообщением - в основном текстовым документом XML. Вы не отправляете через объект .NET! Все, что вы обмениваетесь, - это представление данных вашего контракта с данными, ничего более.
Так что в вашем случае прокси на стороне клиента будет иметь новый класс, который выглядит как тот, который использует сервер - по крайней мере, на уровне сериализации на проводе - но он будет не содержать Calculate
метод. Метод Calculate
, который вы вызываете, указан в договоре на обслуживание - это , а не тот, который у вас есть.
В вашем конкретном примере тоже - вы, кажется, смешиваете [DataMember] и определение интерфейса сервиса. Избегайте этого любой ценой. Кроме того, все типы, участвующие в вычислении - наиболее определенно CalculationNode
и CalculationResult
- должны быть представлены как элементы [DataContract], содержащие ряд полей или свойств [DataMember]. Это не ясно из фрагмента кода, который вы опубликовали.