Множественное наследование интерфейса без использования интерфейсов - PullRequest
2 голосов
/ 22 сентября 2009

Да, название не имеет особого смысла, но вот моя ситуация.

У меня есть два интерфейса, скажем, IGen и ITrans. Некоторые из моих классов реализуют IGen, некоторые реализуют ITrans, а некоторые - оба

У ITrans есть один метод (Translate), а у IGen - один метод (Generate). Для классов, которые реализуют как ITrans, так и IGen Generate, просто вызывают Translate.

У меня также есть интерфейс IGenAndTrans, который просто определяется как

public interface IGenAndTrans : IGen , ITrans
{        
}

И у меня есть класс (назовите его Holder), у которого IGenAndTrans является свойством.

[Serializable] //<- Problem
public class Holder
{
    public IGenAndTrans GeneratorAndTranslator { get; set;}
}

Теперь я хочу пометить класс Holder с помощью [SerializableAttribute] и использовать XmlSerializer. Однако я не могу этого сделать, потому что у Holder есть свойство интерфейса. Обычно рекомендуемый подход состоит в том, чтобы сделать IGenAndTrans абстрактным базовым классом и использовать XmlInclude. Я делал это успешно в прошлом.

Однако я не уверен, как это сделать в этом случае. Поскольку многие мои классы реализуют как IGen, так и ITrans, они не могут просто наследовать от абстрактного базового класса. Это означало бы, что мне нужно было бы разделить каждый из этих классов на два класса с соответствующим дублированием кода (так как генерация вызовов переводит большую часть времени)

Какие-нибудь рекомендации (если мне удалось объяснить себя достаточно хорошо)? Может быть, я слишком близок к коду и должен реализовывать его по-другому.

Ответы [ 3 ]

0 голосов
/ 22 сентября 2009

Полагаю, это обман, потому что у меня есть инсайдерская информация, но мне удалось кое-что для себя исправить.

Я понял, что все, что реализовало IGen, также реализовывало ITrans. И я понял, что в каждый класс, который реализовал оба интерфейса Generate, всегда вызывал Translate.

Итак, я создал базовый абстрактный класс GenerateAndTranslate, который имеет одно свойство с именем Translator и одно с именем Generator. Оба они имеют новый тип, называемый TranslatorBase, от которого наследуется все, что ранее реализовывало ITrans.

Это исправление работает только в моем случае, поэтому мне все еще интересно услышать идеи других людей.

0 голосов
/ 23 сентября 2009

Я собирался ответить на ваш вопрос, но понял, что на самом деле не хватает информации / контекста по этой проблеме, чтобы выдвинуть убедительное предложение.

Но общая идея: хранить данные, а неметоды.

Например, если у вас есть класс Tiger и класс Wolf, вы должны ссылаться на них как на Animal вместо IWalk;с другой стороны, если у вас есть класс Tiger и класс Robot, вам, возможно, придется ссылаться на них как на объект, даже если они совместно используют интерфейс IWalk.

Вы должны ссылаться на объекты как на интерфейсы только тогда, когда вам нужны данные, а не методы.

На несвязанной ноте в мире C # существует тенденция к сильному типувсе (что понятно, так как он обеспечивает безопасность типов и проверку ошибок во время компиляции), но всегда есть возможность использовать универсальные типы и приводить их на лету.

0 голосов
/ 22 сентября 2009

, поскольку это автоматическое свойство, возможно, вы могли бы использовать [field: NonSerialized], чтобы указать, что поле поддержки не сериализовано?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...