Сообщество программистов Autodesk в СНГ

ADN Club => AutoCAD .NET API => Тема начата: Алексей (IdeaSoft) от 11-01-2017, 10:28:01

Название: Нулевое значение для Point3d
Отправлено: Алексей (IdeaSoft) от 11-01-2017, 10:28:01
К примеру в VB Net
я могу присвоить структуре Point3d значение Nothing

Код - vb.net [Выбрать]
  1. Dim pnt3d As Point3d = Nothing

а в C# не допускается присвоить значение null;
Код - C# [Выбрать]
  1. Point3d pnt3d = null;

Мне к примеру нужна будет функция, 
которая должна вернуть Point3d
либо в случае неудачи расчета вернет не point3d а как в VB Nothing

Код - C# [Выбрать]
  1. point3d funct(...) {
  2.    try {
  3.      ...
  4.       return p3d;
  5.    }
  6.    catch {return ???;}
  7. }

или все же сделать функцию которая будет
возвращать код завершения в виде int?




Название: Re: Нулевое значение для Point3d
Отправлено: Вильдар от 11-01-2017, 10:32:45
Можно так Point3d?
http://metanit.com/sharp/tutorial/2.17.php
Название: Re: Нулевое значение для Point3d
Отправлено: Александр Пекшев aka Modis от 11-01-2017, 10:33:45
Код - C# [Выбрать]
  1. private Nullable<Point3d> getPoint3D()
  2.         {
  3.             try
  4.             {
  5.                 return Point3d.Origin;
  6.             }
  7.             catch
  8.             {
  9.                 return null;
  10.             }
  11.         }
Название: Re: Нулевое значение для Point3d
Отправлено: Алексей (IdeaSoft) от 11-01-2017, 10:48:00
Nullable<Point3d>
Спасибо.
Так получилось.
Код - C# [Выбрать]
  1. Nullable<Point3d> pnt = getPoint3D();
  2. // И проверить завершение функции так.
  3. if (pnt.Value != null)  {
  4. }
Название: Re: Нулевое значение для Point3d
Отправлено: Владимир Шу от 11-01-2017, 14:46:44
а в C# не допускается присвоить значение null;
допускается
Код - C# [Выбрать]
  1. Gem.Point3d? p = new Autodesk.AutoCAD.Geometry.Point3d(0, 0, 0);
  2. p = null;

Название: Re: Нулевое значение для Point3d
Отправлено: Александр Пекшев aka Modis от 11-01-2017, 14:54:32
Это
Gem.Point3d?
равнозначно этому
Nullable<Point3d>
Название: Re: Нулевое значение для Point3d
Отправлено: Дмитрий Загорулькин от 11-01-2017, 15:23:19
Код - C# [Выбрать]
  1. Nullable<Point3d> pnt = getPoint3D();
  2. // И проверить завершение функции так.
  3. if (pnt.Value != null)  {
  4. }
Проверка будет возвращать всегда либо true (если pnt != null), либо InvalidOperationException (если pnt == null). Почитали бы Вы лучше мануал по ссылке от Вильдара, там отличные примеры есть.
Название: Re: Нулевое значение для Point3d
Отправлено: Дмитрий Загорулькин от 11-01-2017, 16:09:12
Код - C# [Выбрать]
  1. private Nullable<Point3d> getPoint3D()
  2.         {
  3.             try
  4.             {
  5.                 return Point3d.Origin;
  6.             }
  7.             catch
  8.             {
  9.                 return null;
  10.             }
  11.         }
Александр, Вы уверены, что эта конструкция способна вернуть null? :)
Это
Код - C# [Выбрать]
  1. Gem.Point3d?
равнозначно этому
Код - C# [Выбрать]
  1. Nullable<Point3d>
Это так, но первый вариант гораздо компактнее и на практике именно он обычно используется.
Название: Re: Нулевое значение для Point3d
Отправлено: Александр Пекшев aka Modis от 11-01-2017, 16:15:58
Александр, Вы уверены, что эта конструкция способна вернуть null?
Я показывал пример, чтобы автор вопроса понял суть использования. Мой пример всегда будет возвращать точку начала координат )) Как там будет делать автор - я не в курсе
Это так, но первый вариант гораздо компактнее и на практике именно он обычно используется.
Дык само собой разумеющееся )) И я так-же и пишу "компактнее", но в данном ответе написал так все по той же причине - для более полного понимания
Название: Re: Нулевое значение для Point3d
Отправлено: Дмитрий Загорулькин от 11-01-2017, 16:32:44
Кстати, вместо Nullable часто гораздо удобнее использовать метод с выходным параметром:
Код - C# [Выбрать]
  1. /// <summary>
  2. /// Получение точки методом пользовательского ввода
  3. /// </summary>
  4. /// <param name="point">Выходной параметр - полученная точка</param>
  5. /// <returns>true - точка получена, false - точка не получена</returns>
  6. public static bool GetPoint3D(out Point3d point)
  7. {
  8.     Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;  
  9.     PromptPointResult ptRes = ed.GetPoint("\nSelect point: ");
  10.     point = ptRes.Value;
  11.     return ptRes.Status == PromptStatus.OK;              
  12. }
  13.  
Использование метода:
Код - C# [Выбрать]
  1. Point3d pt;
  2. // Если точку получили
  3. if (GetPoint3D(out pt))
  4. {
  5.     // Используем точку. Например, вычислим вектор:
  6.     Vector3d ptVect = pt - Point3d.Origin;        
  7. }
  8.  
Название: Re: Нулевое значение для Point3d
Отправлено: Дима_ от 22-01-2017, 19:35:35
Кстати, вместо Nullable часто гораздо удобнее использовать метод с выходным параметром
Ну насчет удобства это вопрос конечно субъективный, но ИХМО выходные параметры это аттавизм - nullable (или если брать функциональных подход, то опциональный) параметр - это гораздо более гибкий подход (например в отличие от примера выше его можно и передать любому "адресату" с отсутствующим значением) + опять-таки выходной параметр очень плохо дружит с параллельными вызывами, да и просто с нелинейными алгоритмами. В общем я бы не рекомендовал их использовать в принципе, я например, если таковые есть в "сторонних" api - почти всегда "заворачиваю" их в "опциональную" обертку.
Название: Re: Нулевое значение для Point3d
Отправлено: Дмитрий Загорулькин от 23-01-2017, 00:59:09
Да, действительно, субъективный. Лично мне гораздо больше по душе использование вспомогательных методов с out параметром и возвращаемым булевым значением. По мне, это более логичный подход, чем создавать Nullable обертку и выполнять лишние преобразования. Эти преобразования, к тому же, снижают производительность. Но это мелочи. Главное, что мне так больше нравится :)
Просто для сравнения, без комментариев:
Извините, вам запрещён просмотр содержимого спойлеров.
Название: Re: Нулевое значение для Point3d
Отправлено: Дима_ от 23-01-2017, 06:57:11
Ну если будет время набросайте еще этюд (можно и не выкладывать, а так для себя в уме) где мы запрашиваем у пользователя несколько точек чисел (либо по количеству, либо "пока вводит" - как больше нравится) и возвращаем коллекцию (опять-таки - любую - на Ваше усмотрение) с ними.
Название: Re: Нулевое значение для Point3d
Отправлено: Дмитрий Загорулькин от 23-01-2017, 15:39:59
Я же не призываю всегда и везде вместо Nullable использовать out параметры. Есть случаи, когда использование Nullable более разумно и удобно, чем другие способы.
Название: Re: Нулевое значение для Point3d
Отправлено: avc от 15-02-2017, 13:22:21
Не обязательно null использовать. Можно, например, использовать double.NaN:
Код - C# [Выбрать]
  1.   public static class Point3dExt
  2.   {
  3.     /// <summary>
  4.     /// Для возврата из функций признака что нет точки
  5.     /// </summary>
  6.     public static Point3d NanPoint = new Point3d(double.NaN, double.NaN, double.NaN);
  7.  
  8.     public static bool IsNan(this Point3d point)
  9.     {
  10.       return double.IsNaN(point.X) || double.IsNaN(point.Y) || double.IsNaN(point.Z);
  11.     }
  12. ...
и далее используем
Код - C# [Выбрать]
  1. Point3d cntr = Point3dExt.NanPoint;
  2. ....
  3. if (cntr.IsNan()) ....
Название: Re: Нулевое значение для Point3d
Отправлено: Дмитрий Загорулькин от 15-02-2017, 13:45:21
Тоже вариант, но это не универсальное решение. У целочисленных типов, например, нет значения NaN.
Название: Re: Нулевое значение для Point3d
Отправлено: avc от 15-02-2017, 14:13:09
Для обеих структур-точек (Point2d и Point3d) - универсальное :) И есть маленькое преимущество по ставнению с Nullable  - я не создаю новый тип данных и значит не надо писать ".Value" в каждом вызове каждой функции API. Хотя с другой стороны больше шанс забыть проверку на NaN... Так что на вкус и цвет...
Идеально было б, если у этих структур изначально был IsNull как у ObjectId и всех остальных объектов... эххх
Название: Re: Нулевое значение для Point3d
Отправлено: Дима_ от 15-02-2017, 16:25:31
И есть маленькое преимущество по ставнению с Nullable  - я не создаю новый тип данных и значит не надо писать ".Value"
Ваше решение конечно "креативное", но с моей точки зрения "опасное". Про опциональные типы (и как их подвид Nullable) - изначальная логика их в том, что передавать их надо в "первозданном" виде до "развертывания", а когда необходимо сделать проверку на наличие значения, там практически в 100% случаев идет ветвление программы (типа есть у нас значение или нет). Просто в функциональных языках (откуда собственно и "растут ноги" данного механизма), на данный тип всегда есть шаблон проверки, а .Value конечно применять не надо (это просто C# нормально с ними работать не умеет - формально вроде типы такие есть, а обертки для них не предусмотрено концепцией).
Пример как реализуется такое на F#:
Код - F# [Выбрать]
  1.  ptOpt|>function //ptOpt - имя опционального значения
  2.    |Some(pt)-> /// здесь идет ветвь программы с объявленным именем pt содержащие точку (тип выводится автоматом)
  3.    |None-> //здесь ветвь при отсутствии значения
  4.  
Название: Re: Нулевое значение для Point3d
Отправлено: avc от 15-02-2017, 16:44:23
Простите убогого - ничего не понял :) Теоретик программирования я никакой, я инженер.
Ветвление программы конечно нужно - я про это уже написал - есть шанс забыть проверку на NaN. Абсолютно точно так же можно лохануться, забыв проверку на null, но там необходимость извлечения базового Value из Nullable типа может сработать как напоминалка.
Кстати, в этой теме писали, что на бейсике можно структуре Nothing присвоить. Так что получается мой коммент только про C#
Название: Re: Нулевое значение для Point3d
Отправлено: Дима_ от 15-02-2017, 19:04:57
Ну если простыми словами - на уровне компилятора объединяются в одно три действия проверка значения, выделение его "составляющей" (если она есть) и переход на соответствующую ветку выполнения.