Почему этот тип объекта меняется на меня

1

В инструментах dev он отображается следующим типом:

IClass {Class23}

В отладчике (во время работы) он отображается как следующий тип:

Class23

IClass и Class23 имеют разные свойства, и кажется, что я могу получить к нему доступ, пока он работает как тип, но он не Class23 когда я пытаюсь Class23 свойства Class23 потому что intellisense хочет, чтобы я вводил свойства для IClass. Может ли кто-нибудь объяснить это поведение и как я должен получить доступ к свойствам Class23 когда объект является IClass {Class23}?

Я пробовал это, но он просто возвращает null:

Class23 myclass = Function(returns IClass {Class23}) as Class23

Помогите!


Некоторый код, не уверен, что это помогает:

   Bucket Cats = Dictionary1["key1"] as Bucket;
   IEnumerable<IClass> links = Cats.Links;

   // this should actually be 'Class23'
   var Name = links.ElementAt(0).Name; //<--Error
  • 1
    Думаю, это поможет, если вы разместите более полную версию своего кода.
  • 1
    Можете ли вы очень четко понять, какой язык вы используете, и как объявлены Class23 и IClass ? Я предполагаю public interface IClass {...} и public class Class23 : IClass {...} - но ...? Кроме того: параметр, локальный или поле, о котором вы говорите: как это объявлено? как IClass ? или как Class23 ?
Показать ещё 10 комментариев
Теги:

1 ответ

5
Лучший ответ

С обновлением:

IEnumerable<IClass> links = Cats.Links;

// this should actually be 'Class23'
var Name = links.ElementAt(0).Name; //<--Error

Ошибка здесь - ваше ожидание. Если у вас есть последовательность IClass, то ElementAt(0) возвращает IClass. Вы не получаете автоматическое кастинг (если вы не обманываете, а: нет). Если вы знаете, что этот элемент является Class23, тогда:

var Name = ((Class23)links.ElementAt(0)).Name; // could also use .First()

Вы также можете использовать:

IEnumerable<Class23> links = Cats.Links.Cast<Class23>();

однако, честно говоря, я не думаю, что вы вообще должны смотреть в интерфейс. Если полезно, чтобы IClass отображал Name, добавьте Name в interface.


В инструментах dev он отображается следующим типом:

Похоже, что "это", на которое вы ссылаетесь, статически вводится в качестве IClass, и ему был предоставлен экземпляр класса Class23 который реализует IClass. Это нормально и нормально - там ничего плохого (кроме имен). Но вся точка интерфейса заключается в том, что вам обычно не нужно разговаривать с членами типа: вам нужно будет только API, открытый через интерфейс. Если вам нужно больше: вы нарушили абстракцию. Иногда, однако, да - вам нужно разбить абстракцию, например, на особый случай. В этом случае... cast:

IClass foo = ...


if(foo is Class23) {
    var bar = (Class23)foo;
    bar.SomeClassMember = 42;
}
  • 0
    Просто небольшое дополнение. Если вы не хотите прерывать абстракцию, вы можете добавить свойство Name в Interface (интерфейсы могут содержать свойства). Делайте это только в том случае, если добавление кажется разумным с точки зрения всех классов, реализующих интерфейс.
  • 0
    @ user2184057 так, немного похоже на то, где я говорю: «Однако, честно говоря, я не думаю, что вам вообще следует заглядывать в интерфейс. Если для IClass полезно выставлять Name, то добавьте Name в интерфейс».

Ещё вопросы

Сообщество Overcoder
Наверх
Меню