C # — Реализация частного класса с двумя общедоступными интерфейсами, затем приведение к ним обоим? Плохая идея?

#c# #design-patterns

#c# #шаблоны проектирования

Вопрос:

Считается ли это хорошей идеей? Введите приведение одного и того же класса к двум разным интерфейсам, которые он реализует. Я думаю, что это хорошая идея .. но я не уверен.

 public interface Abc
{
    int xyz { get; }
}

public interface Xyz
{
    int abc { get; }
}

internal class MyClass : Abc, Xyz
{

    public int xyz
    {
        get
        {
            return 0;
        }
    }

    public int abc
    {
        get
        {
            return 1;
        }
    }
}

        var myclass = new MyClass();

        var abc = myclass as Abc;
        var xyz = myclass as Xyz;
  

Ответ №1:

Если он реализует интерфейс, вам не нужно будет приводить его.

Используйте свойства из интерфейса.

Комментарии:

1. о, вы имеете в виду Abc abc = myclass; … звучит потрясающе!

Ответ №2:

Я думаю, это одна из причин, по которой были введены интерфейсы. При использовании interface, в конце концов, вам все равно, какой конкретный класс его реализует, до тех пор, пока он реализует этот интерфейс правильно.

Кроме того, вам не нужно приводить. Назначение класса, реализующего интерфейс, и переменной этого интерфейса неявно.

Ответ №3:

Да, это хорошая идея, особенно если ваши классы выполняют разные роли. Abc и Xyz, возможно, не лучшие примеры, но что-то вроде ICanValidate, IHaveDefault, IHaveAnEngine и т.д. Может быть лучше 🙂

Где такой дизайн блестит, так это когда определенная функциональность необязательна. Возьмем пример ICanValidate: где-то в вашем конвейере сохранения вы безопасно приводите свою сущность к ICanValidate. Если он возвращает null, вы игнорируете его; однако, если он возвращает интерфейс, который вы можете вызвать entity.IsValid() .

Просто замечание по приведению. В некоторых ответах указано, что вам не нужно приводить, когда интерфейс реализован. Это верно для неявной реализации — для явного внедрения вам потребуется приведение. Но я думаю, это было бы довольно очевидно 🙂

Ответ №4:

Например, нет вопроса о том, хорошо или плохо вводить приведение. List реализует IList и IEnumerable. когда требуется итерация в списке, используется IEnumerable, а когда необходимо выполнить операцию со списком (например, добавить элемент), необходимо использовать IList.

итак, это зависит от функциональности (из какого интерфейса), которая вам нужна. Также вам не нужно приведение, когда интерфейс реализован классом.

Ответ №5:

Прежде всего. Если вы хотите, чтобы другие использовали ваш код, вам действительно следует следовать Рекомендациям по проектированию для разработки библиотек классов. Похоже, вы используете рекомендации по именованию, используемые в Java.

Единственная причина сделать что-то внутреннее — это запретить другим создавать класс. Это все еще возможно, хотя и с использованием отражения. Кроме этого, нет никаких причин. Если вы не хотите, чтобы другие расширяли ваш класс, просто создайте его sealed . Но у вас также должна быть действительно веская причина для этого.

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