Почему брошенный к интерфейсу?

Возможно, есть способ сделать это, изменив способ обновления модели; однако, кроме возможности найти способ зарегистрировать / отменить регистрацию часов в операторе if; это может быть не очень хорошая идея.

37
задан HerbalMart 25 September 2012 в 11:16
поделиться

11 ответов

Существует только одна причина при фактической необходимости в броске: Когда документ имеет базовый тип фактического объекта, который реализует IStorable. Позвольте мне объяснить:

public class DocBase
{
  public virtual void DoSomething()
  {

  }
}

public class Document : DocBase, IStorable
{
  public override void DoSomething()
  {
    // Some implementation
    base.DoSomething();
  }

  #region IStorable Members

  public void Store()
  {
    // Implement this one aswell..
    throw new NotImplementedException();
  }

  #endregion
}

public class Program
{
  static void Main()
  {
    DocBase doc = new Document();
    // Now you will need a cast to reach IStorable members
    IStorable storable = (IStorable)doc;
  }
}

public interface IStorable
{
  void Store();
}
17
ответ дан Jeroen Landheer 27 November 2019 в 04:26
поделиться

Поскольку Вы хотите ограничить себя только методами, предоставленными интерфейсом. При использовании класса Вы рискуете называть метод (непреднамеренно), это не часть интерфейса.

21
ответ дан Tundey 27 November 2019 в 04:26
поделиться

Если объект реализует интерфейс явно (public void IStorable.StoreThis(...)), что кастинг является самым легким способом на самом деле достигнуть интерфейсных участников.

15
ответ дан James Curran 27 November 2019 в 04:26
поделиться

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

public interface IFoo
{
     void Display();
}
public interface IBar
{
     void Display();
}

public class MyClass : IFoo, IBar
{
    void IBar.Display()
    {
        Console.WriteLine("IBar implementation");
    }
    void IFoo.Display()
    {
        Console.WriteLine("IFoo implementation");
    }
}

public static void Main()
{
    MyClass c = new MyClass();
    IBar b = c as IBar;
    IFoo f = c as IFoo;
    b.Display();
    f.Display();
    Console.ReadLine();
}

Это отобразилось бы

реализация IBar
реализация IFoo

13
ответ дан Ramesh 27 November 2019 в 04:26
поделиться

Довольно трудно сказать без большего количества контекста. Если переменная doc, как объявляют, является типом, который реализует интерфейс, то бросок избыточен.

, Какую версию книги Вы читаете? Если это "Запрограммирует C# 3.0 то", я взгляну сегодня вечером, когда я буду дома.

РЕДАКТИРОВАНИЕ: Как мы видели в ответах до сих пор, здесь существует три потенциальных вопроса:

  • , Почему брошенный в операторе, показанном в вопросе? (Ответ: Вы не имеете к тому, если doc имеет соответствующий тип времени компиляции)
  • , Почему когда-либо уместно явно бросить к реализованному интерфейсному или базовому классу? (Ответ: явная интерфейсная реализация как показано в другом ответе, и также ради выбора менее определенной перегрузки при передаче броска оценивает как аргумент.)
  • , Почему использование интерфейс вообще? (Ответ: работа с интерфейсным типом означает, что Вы менее восприимчивы к изменениям в конкретном типе позже.)
10
ответ дан Jon Skeet 27 November 2019 в 04:26
поделиться

Эти doc объект мог бы иметь тип, который реализует членов IStorable лет явно, не добавляя их к классам основной интерфейс (т.е. их можно только назвать через интерфейс).

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

3
ответ дан Christian Klauser 27 November 2019 в 04:26
поделиться

Существует много хороших ответов здесь, но я действительно не думаю, что они отвечают, ПОЧЕМУ Вы на самом деле ХОТИТЕ использовать самый строгий возможный интерфейс.

причины не включают Ваше начальное кодирование, они включают в следующий раз, когда Вы посещаете или осуществляете рефакторинг код - или когда кто-то еще делает это.

Скажем, Вы хотите кнопку и помещаете ее на Ваш экран. Вы получаете кнопку, или переданную в или от другой функции, как это:

Button x=otherObject.getVisibleThingy();
frame.add(x);

Вы, оказывается, знаете, что VisibleThingy является кнопкой, он возвращает кнопку, таким образом, все прохладно здесь (никакой требуемый бросок).

Теперь, позволяет, говорят, что Вы осуществляете рефакторинг VisibleThingy для возврата выключателя вместо этого. Теперь необходимо осуществить рефакторинг метод, потому что Вы знали слишком много о реализации.

, Так как Вам только НУЖНЫ методы в Компоненте (родитель и кнопки и Переключателя, который, возможно, был интерфейсом - то же самое в значительной степени в наших целях), если бы Вы записали что первая строка как это:

Component x=(Component)otherObject.getVisibleThingy();

Вы ничего не должны были бы осуществлять рефакторинг - это будет просто работать.

Это - очень простой случай, но это может быть намного более сложно.

, Таким образом, я предполагаю, что сводка была бы то, что интерфейс является особенным методом "Просмотреть" Ваш объект - как рассмотрение его через фильтр... можно только видеть некоторые части. Если можно ограничить представление достаточно, объект может "Превратиться" позади конкретного представления и не произвести что-либо в текущем мире - очень мощный прием абстракции.

2
ответ дан Bill K 27 November 2019 в 04:26
поделиться

Лучшая причина, почему Вы бросили бы к интерфейсам, будет состоять в том, если Вы напишете код против объектов, и Вы не знаете, какой бетон вводят, они, и Вы не хотите.

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

Вот простой пример:

public interface IText
{
   string Text { get; }
}

public interface ISuperDooper
{
   string WhyAmISuperDooper { get; }
}

public class Control
{
   public int ID { get; set; }
}

public class TextControl : Control, IText
{
   public string Text { get; set; }
}

public class AnotherTextControl : Control, IText
{
   public string Text { get; set; }
}

public class SuperDooperControl : Control, ISuperDooper
{
   public string WhyAmISuperDooper { get; set; }
}

public class TestProgram
{
   static void Main(string[] args)
   {
      List<Control> controls = new List<Control>
               {
                   new TextControl
                       {
                           ID = 1, 
                           Text = "I'm a text control"
                       },
                   new AnotherTextControl
                       {
                           ID = 2, 
                           Text = "I'm another text control"
                       },
                   new SuperDooperControl
                       {
                           ID = 3, 
                           WhyAmISuperDooper = "Just Because"
                       }
               };

       DoSomething(controls);
   }

   static void DoSomething(List<Control> controls)
   {
      foreach(Control control in controls)
      {
         // write out the ID of the control
         Console.WriteLine("ID: {0}", control.ID);

         // if this control is a Text control, get the text value from it.
         if (control is IText)
            Console.WriteLine("Text: {0}", ((IText)control).Text);

         // if this control is a SuperDooperControl control, get why
         if (control is ISuperDooper)
            Console.WriteLine("Text: {0}", 
                ((ISuperDooper)control).WhyAmISuperDooper);
      }
   }
}

запущение этой небольшой программы дало бы Вам следующий вывод:

идентификатор: 1

текст: я - текстовое управление

идентификатор: 2

текст: я - другое текстовое управление

идентификатор: 3

текст: Просто, поскольку

Уведомление, что я не должен был писать код в методе DoSomething, который потребовал, чтобы я знал что-либо обо всех объектах, что я работал над тем, чтобы быть конкретными типами объектов. Единственная вещь, которую я знаю, состоит в том, что я работаю над объектами, которые являются, по крайней мере, экземпляром класса Управления. Я могу тогда использовать интерфейс для обнаружения то, что еще они могли бы иметь.

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

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

2
ответ дан Dean Poulin 27 November 2019 в 04:26
поделиться

Как был отмечен, кастинг лишний и не необходимым. Однако это - более явная форма кодирования, которое было бы полезно для новичков в помощи их пониманию.

Во вводном учебнике, лучше явно действовать, вместо того, чтобы позволять compliler сделать вещи неявно, которые более сбивали бы с толку новичков.

"документ" не имеет типа "IStorable", таким образом, это сбивало бы с толку новичков, чтобы видеть, что он присваивается isDoc. Путем явного кастинга автор (книги и кода) говорит, что документ может быть литым к объекту IStorable, но это не ТО ЖЕ как объект IStorable.

1
ответ дан DevinB 27 November 2019 в 04:26
поделиться

Точка, объект (где Вы получали его?) май не реализует интерфейс, в этом случае исключение выдается, который может быть пойман и имел дело с. Конечно, можно использовать "," оператор для проверки, и "как" оператор для кастинга вместо броска C-стиля.

0
ответ дан royatl 27 November 2019 в 04:26
поделиться

Допускать самое отделения между частями кода...

См. следующую статью для больше: Интерфейсы

0
ответ дан Tom Deleu 27 November 2019 в 04:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: