Переменная ссылки на интерфейс ISomeInterface = classsthatimplementsit

#c# #asp.net #asp.net-mvc-5

#c# #asp.net #asp.net-mvc-5

Вопрос:

В настоящее время я изучаю ASP.NET MVC 5. Я застрял в одном месте книги под названием Внедрение зависимостей. Я сделаю все возможное, чтобы научиться его использовать, но прежде чем я это сделаю, я хотел бы, чтобы вы мне помогли. Я начал изучать C # несколько недель назад, и единственное, что я еще не понял, это интерфейс. Я знаю, зачем и когда его создавать, но я не совсем понимаю, когда дело доходит до создания ссылочных переменных.

Допустим, у меня есть интерфейс под названием IValueCalculator. Тогда у меня есть класс LINQValueCalculator, который реализует IValueCalculator. Теперь возникает мое недопонимание.

 LINQValueCalculator referenceVariable = new LINQValueCalculator();
  

Это создаст новый экземпляр и будет связано с referenceVariable .
Затем я могу использовать все, что интерфейс сказал мне использовать, и любые добавленные материалы к классу.

Но что, если я сделаю это…

 IValueCalculator referenceVariable = new LINQValueCalculator();
  

В чем разница? Могу ли я по-прежнему делать то же самое, что и раньше, или что-то изменилось?

Что, если бы у меня было что-то вроде этого

 public class ShoppingCart
{
    private IValueCalculator calc;

    public ShoppingCart(IValueCalculator calcParam)
    {
        calc = calcParam;
    }
  

Это означает, что я могу помещать только ссылки на те объекты, которые правильно реализуют этот интерфейс? Или я ошибаюсь?

Когда я действительно пойму суть всего этого, я продолжу изучать Ninject (DI).

Ответ №1:

Базовый объект по-прежнему является a LINQValueCalculator , но вы можете ссылаться только на IValueCalculator методы и свойства во время использования referenceVariable , потому что эта переменная является просто интерфейсом.

Чтобы использовать любое из свойств LINQValueCalculator , вам нужно будет привести переменную. Вы можете делать это каждый раз, когда вам нужно его использовать:

 ((LINQValueCalculator)referenceVariable).SomeMethod();
  

или только один раз:

 var anotherReference = (LINQValueCalculator)referenceVariable;
  

Здесь anotherReference и referenceVariable являются ссылками на один и тот же объект, поэтому изменения в одном будут отражены в другом.

Использование интерфейса означает, что вы можете передать объект другому коду, который не знает (или не должен знать) о LINQValueCalculator , но действует на свойства и методы IValueCalculator .

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

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

2. @xForcer правильно. Мы используем интерфейсы, потому что нам все равно, как это реализовано, нам просто важно, чтобы он реализовал этот интерфейс. Это позволяет нашему коду не быть слишком тесно связанным, что делает его более тестируемым и упрощает замену элементов, не нарушая другие вещи. Я предлагаю это отличное видео .

3. Спасибо @mason за укрепление моих знаний!

Ответ №2:

В чем разница? Могу ли я по-прежнему делать то же самое, что и раньше, или что-то изменилось?

Вы можете делать то же самое 🙂 Если только конкретный тип не предлагает больше методов, чем интерфейс!

Это означает, что я могу помещать только ссылки на те объекты, которые правильно реализуют этот интерфейс? Или я ошибаюсь?

И вы правы !

Преимущества использования интерфейса в последнем случае заключается в том, что вы можете получить объект, который реализует IValueCalculator , но вас (на самом деле) не волнует конкретный тип.

Если вы решите создать второй конкретный тип, который реализует IValueCalculator (может быть, более производительный?), Вы можете сделать это и внедрить его в ShoppingCart конструктор без изменения ShoppingCart кода!