Как внедрить EXPRESS в CSharp наиболее эффективно

Мне нужно создать библиотеку классов на основе схемы EXPRESS. Схема EXPRESS имеет типы и сущности, похожие на следующие:

ENTITY IfcRoot
 ABSTRACT SUPERTYPE OF (ONEOF
    (IfcObjectDefinition
    ,IfcPropertyDefinition
    ,IfcRelationship));
    GlobalId : IfcGloballyUniqueId;
    OwnerHistory : OPTIONAL IfcOwnerHistory;
    Name : OPTIONAL IfcLabel;
    Description : OPTIONAL IfcText;
 UNIQUE
    UR1 : GlobalId;
END_ENTITY;

Здесь GlobalId, OwnerHistory, Name и Description - все это свойства класса IfcRoot. Например, тип свойства "Имя" - это IfcLabel, который задается как ТИП в схеме EXPRESS и выглядит следующим образом:

TYPE IfcLabel = STRING(255);
END_TYPE;

Этот тип имеет тип String или массив строк. В моем подходе я реализовал все сущности в схеме и все типы в схеме как классы в chsharp. Поэтому я написал программу чтения строк, которая читает схему и создает на ее основе сущности (~800) и типы (~400). IfcLabel в моей реализации выглядит так:

public class IfcLabel
{
   public string _value { get; set; }
}

Все это прекрасно работает, но когда я хочу использовать свою библиотеку классов, это действительно трудоемко из-за того факта, что каждый тип атрибута является самим классом. Это значит, что я должен сначала создать объект класса IfcLabel и назначить свойство _value, а затем создать свой объект IfcRoot и назначить свойство Name как объект IfcLabel. У кого-нибудь есть идея, как я могу реализовать это умнее? Следует добавить еще одну вещь: все типы должны иметь метод и наследоваться от класса с именем IfcBase, так что это все еще должно быть возможным. Мне также не разрешается напрямую изменять тип свойства с IfcLabel на строку, что в любом случае оно и есть.

2 ответа

Чтобы упростить IfcLabel, вы можете использовать неявную перегрузку операторов, чтобы можно было рассматривать IfcLabel как String, без Name._value через ваш код.

Если это больше, чем образовательный проект, возможно, стоит посмотреть, как другие справились с этим. Например, проект Xbim имеет библиотеки C# для чтения и записи файлов IFC. Для справки вот их реализация IfcRoot и IfcLabel:

https://github.com/xBimTeam/XbimEssentials/blob/master/Xbim.Ifc4/Kernel/IfcRoot.cs#L58 https://github.com/xBimTeam/XbimEssentials/blob/master/Xbim.Ifc4/MeasureResource/IfcLabel.cs

Если вам действительно нужно работать с файлами IFC EXPRESS на коммерческой основе, я могу порекомендовать посмотреть на закаленную в боях библиотеку, такую ​​как XBim или IfcOpenShell, поскольку это сложный домен, чтобы писать свои собственные с нуля.

Все еще не хорошо, но по крайней мере немного лучше, потому что я могу сложить всю декларацию объекта, чтобы она выглядела немного яснее в Visual Studio, я сделал это:

IfcAlignment2DVerSegLine ifcVerSegLine = new IfcAlignment2DVerSegLine()
{
   m_StartDistAlong = new IfcLengthMeasure()
  {
     _value = verTangent.StartStation
  },
   m_HorizontalLength = new IfcPositiveLengthMeasure()
  {
     _value = new IfcLengthMeasure()
     {
        _value = verTangent.Length
     }
  },
   m_StartGradient = new IfcRatioMeasure()
  {
     _value = verTangent.Grade
  },
   m_StartHeight = new IfcLengthMeasure()
  {
     _value = verTangent.StartElevation
  }
};

складывается в:

IfcAlignment2DVerSegLine ifcVerSegLine = new IfcAlignment2DVerSegLine()...;

Так что это работает для моей цели на данный момент. Конечно, если этот продукт когда-либо станет коммерческим, мне придется переписать свое раннее связывание.

Другие вопросы по тегам