Как создать универсальный метод для Entity и DBObject?

Автор Тема: Как создать универсальный метод для Entity и DBObject?  (Прочитано 7472 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Всем привет!
Как оказалось, Civil 3D API спроектирован таким образом, что Autodesk.Civil.DatabaseServices.Entity не является наследником от Autodesk.Civil.DatabaseServices.DBObject. Очень удивительный факт! Посмотреть хотя бы на их интерфейсы:
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.DatabaseServices;
  2. using Autodesk.AutoCAD.Runtime;
  3. using System;
  4.  
  5. namespace Autodesk.Civil.DatabaseServices
  6. {
  7.     [Wrapper("AeccDbTreeNode")]
  8.     public class DBObject : AutoCAD.DatabaseServices.DBObject
  9.     {
  10.         protected internal DBObject(IntPtr unmanagedPointer, bool autoDelete);
  11.  
  12.         public virtual string Description { get; set; }
  13.         public virtual string Name { get; set; }
  14.         public virtual object Document { get; }
  15.         public virtual object Application { get; }
  16.     }
  17. }
Код - C# [Выбрать]
  1. using Autodesk.Aec.DatabaseServices;
  2. using Autodesk.AutoCAD.DatabaseServices;
  3. using Autodesk.AutoCAD.Runtime;
  4. using System;
  5.  
  6. namespace Autodesk.Civil.DatabaseServices
  7. {
  8.     [Wrapper("AeccDbEntity")]
  9.     public class Entity : Aec.DatabaseServices.Entity
  10.     {
  11.         protected internal Entity(IntPtr unmanagedPointer, bool autoDelete);
  12.  
  13.         public bool IsReferenceStale { get; }
  14.         public bool IsReferenceValid { get; }
  15.         public bool IsReferenceSubObject { get; }
  16.         public bool IsReferenceObject { get; }
  17.         public override AutoCAD.DatabaseServices.ObjectId StyleId { get; set; }
  18.         public virtual string StyleName { get; set; }
  19.         public bool ShowToolTip { get; set; }
  20.         public virtual string DisplayName { get; }
  21.         public virtual string Description { get; set; }
  22.         public virtual string Name { get; set; }
  23.         public virtual object Document { get; }
  24.         public virtual object Application { get; }
  25.     }
  26. }
Явно одно включает в другое. Но их сделали отдельными несвязанными объектами. Из-за этого есть трудность - не сделать общего шаблонного метода для них. Например, такого вида:
Код - C# [Выбрать]
  1. public static string GetName<T>(T obj) where T : Autodesk.Civil.DatabaseServices.DBObject
  2. {
  3.     return obj.Name;
  4. }
  5.  
Пример простой. В реальности есть довольно полезный базовый класс для получения данных из DBObject. Появилась необходимость получить те же данные из Entity - а использовать уже готовый класс не получается! Либо делать копию класса для Entity, либо что-то хитрое пытаться придумывать...
Возможно, есть какие-то инструменты в C#/Net.Framework, чтобы сделать один Generic класс для объектов разного типа, но со схожими интерфейсами? Или какой-то другой выход из ситуации?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
А что у нас в Aec.DatabaseServices.Entity ?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Или какой-то другой выход из ситуации?
Наверное Reflection.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
А что у нас в Aec.DatabaseServices.Entity ?
Код - C# [Выбрать]
  1. using Autodesk.Aec.DatabaseServices;
  2. using Autodesk.Aec.Geometry;
  3. using Autodesk.AutoCAD.DatabaseServices;
  4. using Autodesk.AutoCAD.Geometry;
  5. using Autodesk.AutoCAD.Runtime;
  6. using System;
  7. using System.Collections.Specialized;
  8. using System.ComponentModel;
  9. using System.Drawing;
  10.  
  11. namespace Autodesk.Aec.DatabaseServices
  12. {
  13.     [Wrapper("AecDbEntity")]
  14.     public abstract class Entity : Curve, IOverrideOperation
  15.     {
  16.         protected internal Entity(IntPtr unmanagedPointer, bool autoDelete);
  17.  
  18.         [Category("Miscellaneous")]
  19.         public virtual Icon TypeIcon { get; }
  20.         [Category("General")]
  21.         public string Description { get; set; }
  22.         [Category("General")]
  23.         public ProjectState ProjectState { get; set; }
  24.         [Category("General")]
  25.         public virtual string LayerKey { get; }
  26.         [Category("General")]
  27.         public ClassificationCollection Classifications { get; }
  28.         [Category("General")]
  29.         public virtual AutoCAD.DatabaseServices.ObjectId StyleId { get; set; }
  30.         [Category("Miscellaneous")]
  31.         public virtual bool SupportsBaseCurveCommands { get; }
  32.         [Category("Geometry")]
  33.         public virtual Curve BaseCurve { get; }
  34.         [Category("Miscellaneous")]
  35.         public virtual bool SupportsProfileCommands { get; }
  36.         [Category("Miscellaneous")]
  37.         public bool NeedsPromoting { get; set; }
  38.         [Category("Miscellaneous")]
  39.         public bool SwappingReferences { get; set; }
  40.         [Category("General")]
  41.         public AutomaticSpaceBoundary AutomaticallyBoundSpaces { get; set; }
  42.         [Category("Miscellaneous")]
  43.         public bool IsHighlighting { get; }
  44.         [Category("Miscellaneous")]
  45.         public virtual string DisplayName { get; }
  46.         [Category("ADVANCED")]
  47.         public OverrideCollection Overrides { get; }
  48.  
  49.         public virtual void GetAutomaticallyBoundSpaces(AutoCAD.DatabaseServices.ObjectIdCollection blockRefPath, out AutomaticSpaceBoundary boundSpaces);
  50.         public virtual Profile GetBaseProfile(out Matrix3d toWcs);
  51.         public virtual void GetLocalExtents(out BoundBlock3d extents);
  52.         public virtual void GetLocalModelCachedExtents(out BoundBlock3d ext);
  53.         public virtual void GetMaterialComponents(out IntegerCollection componentIds, out StringCollection componentNames, out AutoCAD.DatabaseServices.ObjectIdCollection materialIds);
  54.         public virtual void GetMaterialLocations(out IntegerCollection locationIds, out AutoCAD.DatabaseServices.ObjectIdCollection styleIdArray);
  55.         public virtual Profile GetProfile(Plane cutPlane);
  56.         public virtual Profile GetUsageArea(Plane cutPlane);
  57.         public virtual void GetWorldExtents(out BoundBlock3d extents);
  58.         public virtual void SetAutomaticallyBoundSpaces(AutoCAD.DatabaseServices.ObjectIdCollection blockRefPath, AutomaticSpaceBoundary boundSpaces);
  59.         public virtual void SetBaseProfile(Profile profile, Matrix3d matrix);
  60.         public virtual void SetDefaultLayer();
  61.         public virtual void SetLocalExtents(BoundBlock3d extents, int flags);
  62.         public void SetLocalModelExtentsDirty();
  63.         public virtual void SetMaterialComponents(IntegerCollection componentIds, AutoCAD.DatabaseServices.ObjectIdCollection materialIds);
  64.         public virtual void SetToStandard(Database db);
  65.         public virtual void SetWorldExtents(BoundBlock3d extents);
  66.     }
  67. }
Здесь базовый класс Curve - это Autodesk.AutoCAD.DatabaseServices.Curve

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Наверное Reflection.
Ой как не хочется! Может ещё есть варианты?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Здесь базовый класс Curve - это Autodesk.AutoCAD.DatabaseServices.Curve
Ну т.е. на уровне Autodesk.AutoCAD.DatabaseServices.DBObject они в конечном итоге сходятся.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение Дмитрий Загорулькин 04-02-2020, 12:41:03

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Наверное Reflection.
Ой как не хочется! Может ещё есть варианты?
Если честно, то я не думаю, что есть еще какие-то варианты, которые в конечном итоге не сводились бы к Reflection.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Ну т.е. на уровне Autodesk.AutoCAD.DatabaseServices.DBObject они в конечном итоге сходятся.
Да, только там.
В принципе, почему так сделали - понятно. Для Entity надо было получить интерфейс Entity из Aec. А для неграфических объектов Civil 3D эти свойства и методы будут явно лишними. Поэтому, прямого наследования Entity от DBObject и не получилось.
Если честно, то я не думаю, что есть еще какие-то варианты, которые в конечном итоге не сводились бы к Reflection.
Эх, ладно, да будет так! В принципе, даже не очень страшно получается... С учётом того, что я в этот базовый класс буду редко заглядывать, мне этот костыль глаза не будет мозолить :)