C# ссылка на объект не указывает на экземпляр объекта

Автор Тема: C# ссылка на объект не указывает на экземпляр объекта  (Прочитано 15980 раз)

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

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

Оффлайн simson43Автор темы

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Код - C# [Выбрать]
  1. BlockTableRecord lyy;
  2.  
  3.                     foreach (DBDictionaryEntry ly in dbl)
  4.                     {
  5.                         lyy = ly.Value.GetObject(OpenMode.ForWrite) as BlockTableRecord;
  6.                         lyy.AppendEntity(ci);
  7.                         tr.AddNewlyCreatedDBObject(ci, true);
  8.                     }
ругается! на строчку где добавляю объект ci. якобы ссылаюсь на lyy и он пустой.
подозреваю что здесь - lyy = ly.Value.GetObject(OpenMode.ForWrite) as BlockTableRecord; - что то не так сделал.
в чем проблема?
спасибо
« Последнее редактирование: 02-09-2018, 15:14:41 от Александр Ривилис »

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 624
  • Карма: 158
    • ПГСу Бложик
По тому огрызку кода, который Вы показали, вообще не понятно что такое ci, как оно было создано и с какой стати должно добавляться.

Оффлайн simson43Автор темы

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
По тому огрызку кода, который Вы показали, вообще не понятно что такое ci, как оно было создано и с какой стати должно добавляться.

Код - C# [Выбрать]
  1. Circle ci = new Circle();
  2.             ci.Center = new Point3d(0, 0, 0);
  3.             ci.Radius = 5;
проблема не в нем. пробовал просто выводить имя листа на каждом листе. ошибка та же. будто lyy пустой
« Последнее редактирование: 02-09-2018, 15:15:30 от Александр Ривилис »

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 624
  • Карма: 158
    • ПГСу Бложик
Я намекал, что надо бы весь смысловой кусок кода показывать... гадать по кусочкам бесполезно.
что такое dbl, почему Вы открываете объект не через транзакцию ( а она у Вас вроде как есть.. tr), да тут много чего не понятно...

Вы бы код вложили и пояснили чего хотите добиться.

Оффлайн simson43Автор темы

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Код - C# [Выбрать]
  1.  private void buttonFind_Click(object sender, EventArgs e)
  2.         {
  3.             Document doc = App.DocumentManager.MdiActiveDocument;
  4.             Database db = doc.Database;
  5.  
  6.             Circle ci = new Circle();
  7.             ci.Center = new Point3d(0, 0, 0);
  8.             ci.Radius = 5;
  9.  
  10.             using (DocumentLock dl = doc.LockDocument())
  11.             {
  12.                 using (Transaction tr = doc.TransactionManager.StartTransaction())
  13.                 {
  14.                     BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
  15.                    
  16.                     DBDictionary dbl = tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;
  17.  
  18.                     BlockTableRecord lyy;
  19.                     foreach (DBDictionaryEntry ly in dbl)
  20.                     {
  21.                         lyy = ly.Value.GetObject(OpenMode.ForWrite) as BlockTableRecord;
  22.                         lyy.AppendEntity(ci);
  23.                         tr.AddNewlyCreatedDBObject(ci, true);
  24.                     }
  25.                     tr.Commit();
  26.                 }
  27.             }
  28.         }

хочу добраться до пространства каждого листа
« Последнее редактирование: 02-09-2018, 15:15:49 от Александр Ривилис »

Отмечено как Решение simson43 02-09-2018, 22:53:16

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 624
  • Карма: 158
    • ПГСу Бложик
активнее пользуйтесь отладчиком и если не знаете какого типа объект Вам вернет система, используйте DBObject с последующем приведением к нужному типу.
Код - C# [Выбрать]
  1.         private static void buttonFind_Click()
  2.         {
  3.             App.Document doc = App.Application.DocumentManager.MdiActiveDocument;
  4.             Db.Database db = doc.Database;
  5.  
  6.             //Db.Circle ci = new Db.Circle();
  7.             //ci.Center = new Gem.Point3d(0, 0, 0);
  8.             //ci.Radius = 5;
  9.  
  10.             using (App.DocumentLock dl = doc.LockDocument())
  11.             {
  12.                 using (Db.Transaction tr = doc.TransactionManager.StartTransaction())
  13.                 {
  14.                     //Db.BlockTable bt = tr.GetObject(db.BlockTableId,Db. OpenMode.ForRead) as Db.BlockTable;
  15.                     Db.DBDictionary dbl = tr.GetObject(db.LayoutDictionaryId, Db.OpenMode.ForRead) as Db.DBDictionary;
  16.  
  17.                     foreach (Db.DBDictionaryEntry ly in dbl)
  18.                     {
  19.                         //lyy = ly.Value.GetObject(Db.OpenMode.ForWrite) as Db.BlockTableRecord;
  20.                         //lyy.AppendEntity(ci);
  21.                         //tr.AddNewlyCreatedDBObject(ci, true);
  22.  
  23.                         Db.Layout lout = tr.GetObject(ly.Value, Db.OpenMode.ForRead) as Db.Layout;
  24.                         Db.BlockTableRecord lyy = tr.GetObject(lout.BlockTableRecordId, Db.OpenMode.ForWrite) as Db.BlockTableRecord;
  25.  
  26.                         Db.Circle ci = new Db.Circle();
  27.                         ci.Center = new Gem.Point3d(0, 0, 0);
  28.                         ci.Radius = 5;
  29.  
  30.                         lyy.AppendEntity(ci);
  31.                         tr.AddNewlyCreatedDBObject(ci, true);
  32.                     }
  33.                     tr.Commit();
  34.                 }
  35.             }
  36.         }

Оффлайн simson43Автор темы

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
я просто поместил создание окружности в цикл и все заработало. почему?
зачем ее объявлять в каждой итерации? разве нельзя один раз а потом просто вставлять везде?

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 624
  • Карма: 158
    • ПГСу Бложик
я просто поместил создание окружности в цикл и все заработало. почему?
Вот и мне интересно, почему. В строчке:
lyy = ly.Value.GetObject(OpenMode.ForWrite) as BlockTableRecord;
Вы объект типа Layout приводите к типу BlockTableRecord и закономерно получаете null и как перенос только создания окружности помог Вам сделать код рабочим.... загадка.

зачем ее объявлять в каждой итерации? разве нельзя один раз а потом просто вставлять везде?
Нельзя. Вам ведь нужен не один объект, а по объекту на каждом листе, т.е. много объектов, вот и создавайте эти объекты.
Если очень грубо: Когда Вы создали объект, под него был выделен некий диапазон в памяти, когда Вы добавили этот объект в базу чертежа, автокад пометил, что объект из этой области(с этим адресом) уже добавлен в базу чертежа и второй раз его не добавит, т.к. он уже есть.

Оффлайн simson43Автор темы

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
все разобрался! спасибо большое!

Оффлайн simson43Автор темы

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Вы объект типа Layout приводите к типу BlockTableRecord и закономерно получаете null и как перенос только создания окружности помог Вам сделать код рабочим.... загадка.
да это я в другом методе вставил. там через перебор в blocktable добрался до каждого листа и вставил окружности. но этому методу все мое нутро сопротивлялось ибо приходится перебирать все блоки в чертеже, а на больших чертежах это впустую потраченные ресурсы я считаю и драгоценное время.
вот искал другой способ.
нашел! спасибо)

Оффлайн simson43Автор темы

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
а вот еще вопрос.
а можно ли их перебирать не foreach a for?
от 0 до количества листов?
для этого нужно подобие item
есть здесь такое?

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 624
  • Карма: 158
    • ПГСу Бложик
Можно конечно, но вот смысла в это маловато. =о)
Код - C# [Выбрать]
  1.                     Db.DBDictionary dbl = tr.GetObject(db.LayoutDictionaryId, Db.OpenMode.ForRead) as Db.DBDictionary;
  2.  
  3.                     List<Db.ObjectId> listLoutsId = new List<Db.ObjectId>();
  4.                     foreach(Db.DBDictionaryEntry ly in dbl)
  5.                         listLoutsId.Add(ly.Value);
  6.  
  7.                     for (int i = 0; i < dbl.Count; i++)
  8.                     {
  9.                         Db.Layout lout = tr.GetObject(listLoutsId[i], Db.OpenMode.ForRead) as Db.Layout;
  10.                         Db.BlockTableRecord lyy = tr.GetObject(lout.BlockTableRecordId, Db.OpenMode.ForWrite) as Db.BlockTableRecord;
  11.  
  12.                         Db.Circle ci = new Db.Circle();
  13.                         ci.Center = new Gem.Point3d(0, 0, 0);
  14.                         ci.Radius = 5;
  15.  
  16.                         lyy.AppendEntity(ci);
  17.                         tr.AddNewlyCreatedDBObject(ci, true);
  18.  
  19.                     }

Оффлайн simson43Автор темы

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Смысл в этом есть. Просто нужно в зависимомти от ввода пользователя залазить в конкретные листы. Спасибо

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 624
  • Карма: 158
    • ПГСу Бложик
в зависимомти от ввода пользователя залазить в конкретные листы
Код - C# [Выбрать]
  1. Db.Layout lout = tr.GetObject(dbl.GetAt("LayoutName"), Db.OpenMode.ForRead) as Db.Layout;

Оффлайн simson43Автор темы

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Названия листов неивестны. Или все листы или только модель или все все все. Номерами самое оптимальное ро моему.