Лучший способ привести объект к int - PullRequest
151 голосов
/ 14 апреля 2009

Это, вероятно, тривиально, но я не могу придумать лучшего способа сделать это. У меня есть COM-объект, который возвращает вариант, который становится объектом в C #. Единственный способ получить это в int - это

int test = int.Parse(string.Format("{0}", myobject))

Есть ли более чистый способ сделать это? Спасибо

Ответы [ 9 ]

321 голосов
/ 14 апреля 2009

У вас есть несколько вариантов:

  • (int) & mdash; Оператор приведения. Работает, если объект уже является целым числом на некотором уровне в иерархии наследования или если определено неявное преобразование.

  • int.Parse()/int.TryParse() & mdash; Для преобразования из строки неизвестного формата.

  • int.ParseExact()/int.TryParseExact() & mdash; Для преобразования из строки в определенном формате

  • Convert.ToInt32() & mdash; Для преобразования объекта неизвестного типа. Он будет использовать явное и неявное преобразование или реализацию IConvertible, если таковые определены.

  • as int? & mdash; Обратите внимание "?". Оператор as предназначен только для ссылочных типов, поэтому я использовал "?" чтобы обозначить Nullable<int>. Оператор "as" работает как Convert.To____(), но подумайте TryParse(), а не Parse(): он возвращает null, а не вызывает исключение в случае сбоя преобразования.

Из них я бы предпочел (int), если объект на самом деле представляет собой целое в штучной упаковке. В противном случае используйте Convert.ToInt32() в этом случае.

Обратите внимание, что это очень общий ответ: я хочу обратить внимание на ответ Даррена Кларка, потому что я думаю, что он хорошо справляется с рассмотрением особенностей здесь, но пришел поздно и еще не проголосовали. В любом случае он получает мой голос за «принятый ответ», за то, что я также рекомендую (int), за то, что он указал, что в случае неудачи может сработать (int)(short), и за рекомендацию проверить ваш отладчик, чтобы узнать фактический тип времени выполнения.

35 голосов
/ 14 апреля 2009

Активированный (int) myobject должен просто работать.

Если это дает вам недопустимое исключение приведения, то это, вероятно, потому, что тип варианта не VT_I4. Бьюсь об заклад, что вариант с VT_I4 конвертируется в упакованный int, VT_I2 в упакованный короткий и т. Д.

При приведении типа в штучной упаковке допустимо только приведение к типу в штучной упаковке. Например, если возвращенный вариант действительно VT_I2, то (int) (short) myObject должен работать.

Самый простой способ выяснить это проверить возвращенный объект и посмотреть его тип в отладчике. Также убедитесь, что в сборке взаимодействия у вас есть возвращаемое значение, помеченное MarshalAs (UnmanagedType.Struct)

24 голосов
/ 14 апреля 2009
Convert.ToInt(myobject);

Это будет обрабатывать случай, когда myobject равен null и вернет 0, вместо выдачи исключения.

8 голосов
/ 14 апреля 2009

Используйте Int32.TryParse следующим образом.

  int test;
  bool result = Int32.TryParse(value, out test);
  if (result)
  {
     Console.WriteLine("Sucess");         
  }
  else
  {
     if (value == null) value = ""; 
     Console.WriteLine("Failure");
  }
3 голосов
/ 06 июля 2017

Я перечисляю разницу в каждом из способов кастинга. Что за особый тип литейных ручек и нет?

    // object to int
    // does not handle null
    // does not handle NAN ("102art54")
    // convert value to integar
    int intObj = (int)obj;

    // handles only null or number
    int? nullableIntObj = (int?)obj; // null
    Nullable<int> nullableIntObj1 = (Nullable<int>)obj; // null

   // best way for casting from object to nullable int
   // handles null 
   // handles other datatypes gives null("sadfsdf") // result null
    int? nullableIntObj2 = obj as int?; 

    // string to int 
    // does not handle null( throws exception)
    // does not string NAN ("102art54") (throws exception)
    // converts string to int ("26236")
    // accepts string value
    int iVal3 = int.Parse("10120"); // throws exception value cannot be null;

    // handles null converts null to 0
    // does not handle NAN ("102art54") (throws exception)
    // converts obj to int ("26236")
    int val4 = Convert.ToInt32("10120"); 

    // handle null converts null to 0
    // handle NAN ("101art54") converts null to 0
    // convert string to int ("26236")
    int number;

    bool result = int.TryParse(value, out number);

    if (result)
    {
        // converted value
    }
    else
    {
        // number o/p = 0
    }
2 голосов
/ 19 августа 2015
var intTried = Convert.ChangeType(myObject, typeof(int)) as int?;
2 голосов
/ 14 апреля 2009

Там также TryParse .

Из MSDN:

private static void TryToParse(string value)
   {
      int number;
      bool result = Int32.TryParse(value, out number);
      if (result)
      {
         Console.WriteLine("Converted '{0}' to {1}.", value, number);         
      }
      else
      {
         if (value == null) value = ""; 
         Console.WriteLine("Attempted conversion of '{0}' failed.", value);
      }
   }
1 голос
/ 28 ноября 2018

Странно, но принятый ответ кажется неверным в отношении приведения и преобразования в том смысле, что из моих тестов и чтения документации тоже не следует принимать во внимание неявные или явные операторы.

Итак, если у меня есть переменная типа object, а в «коробочном» классе определены неявные операторы, они не будут работать.

Вместо этого еще один простой способ, но на самом деле снижение производительности - это приведение ранее в динамическом режиме.

(INT) (динамическая) MyObject.

Вы можете попробовать это в Интерактивном окне VS.

public class Test
{
  public static implicit operator int(Test v)
  {
    return 12;
  }
}

(int)(object)new Test() //this will fail
Convert.ToInt32((object)new Test()) //this will fail
(int)(dynamic)(object)new Test() //this will pass
1 голос
/ 14 апреля 2009

Может быть Convert.ToInt32 .

Остерегайтесь исключения, в обоих случаях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...