Кращий спосіб віддати об’єкт до int


179

Це, мабуть, банально, але я не можу придумати кращого способу зробити це. У мене є об'єкт COM, який повертає варіант, який стає об'єктом в C #. Єдиний спосіб, коли я можу це зробити в int, це

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

Чи є чистіший спосіб зробити це? Дякую

Відповіді:


362

У вас є кілька варіантів:

  • (int)- У ролях оператора. Працює, якщо об'єкт вже є цілим числом на певному рівні в ієрархії спадкування або якщо визначено неявне перетворення.

  • int.Parse()/int.TryParse() - для перетворення з рядка невідомого формату.

  • int.ParseExact()/int.TryParseExact() - Для перетворення з рядка у певний формат

  • Convert.ToInt32() - для перетворення об'єкта невідомого типу. Він буде використовувати явну та неявну конверсію або реалізацію IConvertible, якщо такі визначені.

  • as int?- Зверніть увагу на "?". asОператор тільки для довідкових типів, і тому я використовував «?» означати а Nullable<int>. Оператор " as" працює як Convert.To____(), але думайте, TryParse()а не Parse(): він повертається, nullа не кидає виняток, якщо конверсія не вдається.

З них я вважаю (int)за краще, якщо об'єкт справді є лише цілим кодом. В іншому випадку використовуйте Convert.ToInt32()в цьому випадку.

Зауважте, що це дуже загальна відповідь: я хочу привернути деяку увагу до відповіді Даррена Кларка, тому що я думаю, що це непогана робота з вирішенням конкретики тут, але прийшов пізно і ще не був проголосований. У будь-якому випадку він отримує мій голос за "прийняту відповідь" за те, що він також рекомендує (int), за те, що вказує, що, якщо це не вдасться, (int)(short)замість цього може працювати, і для того, щоб рекомендувати вам перевірити свій налагоджувач, щоб дізнатися фактичний тип виконання.


Я знайшов точку, яка насправді не була помилкою, але, можливо, надто спростила речі, щоб хтось міг подумати про це. Я вилучив це речення і додав посилання на авторитетну документацію.
Joel Coehoorn

Чи буде прямий ролик працювати з неявним перетворенням? У мене було враження, що це буде суворо робити розпакування, а не будь-які інші перетворення.
Даррен Кларк

Не зовсім відповідь, але читайте це: blogs.msdn.com/ericlippert/archive/2009/03/19/…
Joel

Підсумок у тому, що це, безумовно, робить більше, ніж просто розпаковувати. В іншому випадку, чому ви могли б використовувати його для передачі дубля в інт, наприклад?
Joel Coehoorn

І читаючи деякі інші речі, я, можливо, маю неявні / явні назад, але в будь-якому випадку я думаю, що це зрозуміло.
Joel Coehoorn

41

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

Якщо це дає вам недійсний виняток з амплітуди, можливо, тому що тип варіанту не VT_I4. Моя ставка полягає в тому, що варіант з VT_I4 перетворюється на коробку, а VT_I2 - у коробочку тощо.

Коли ви робите кастинг типу типу в коробці, це справедливо лише для того, щоб передати його типу. Приклад Foe, якщо повернутий варіант насправді є VT_I2, тоді він (int) (short) myObjectповинен працювати.

Найпростіший спосіб це дізнатися - оглянути повернутий об’єкт і переглянути його тип у відладчику. Також переконайтеся, що у збірці interop ви маєте відмічене значення поверненняMarshalAs(UnmanagedType.Struct)


32

Convert.ToInt32 (мій об’єкт);

це буде обробляти випадок, коли мій об’єкт є нульовим і повертає 0, замість того, щоб викидати виняток.


Я отримую "Не вдається розв'язати символ" ToInt ", коли я спробую це. Він працює лише у тому випадку, якщо я використовую напр ToInt32.
Тобіас

Де ми можемо знайти цей метод? Це в .Net Framework Library?
Amir Pourmand امیر پورمند

8

Використовуйте Int32.TryParseнаступним чином.

  int test;
  bool result = Int32.TryParse(value, out test);
  if (result)
  {
     Console.WriteLine("Sucess");         
  }
  else
  {
     if (value == null) value = ""; 
     Console.WriteLine("Failure");
  }

Власне, Parse викликає TryParse та видаляє виняток, якщо TryParse повертає значення false. Тож TryParse не обробляє виняток, оскільки він ніколи не кидає його.
Самуїл

З технічної точки зору вони обидва називають один і той же метод NumberToInt32, але лише Parse викидає винятки, коли це не працює.
Самуїл

TryParse все ще вимагає перетворення варіанту в рядок. Проблема AFAIK не перетворюється з рядка в int, а з варіанту, який є int до фактичного int.
Даррен Кларк

3

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

    // 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
var intTried = Convert.ChangeType(myObject, typeof(int)) as int?;

1
Мені ця відповідь виявилася дуже корисною, я хотів кинути байтовий ящик у int і змусив його працювати Convert.ChangeType. Я б сказав, що це не може бути ідеальною відповіддю для ОП, але це, безумовно, корисно для деяких!
Філіп Паре

1

Також є 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

Дивно, але прийнята відповідь здається невірною щодо кастингу та конвертації, що означає, що з моїх тестів та читання документації він також не повинен враховувати неявні чи явні оператори.

Отже, якщо у мене є об'єкт змінної типу, а у класу "boxed" визначені деякі неявні оператори, вони не працюватимуть.

Натомість ще один простий спосіб, але реально вартістю продуктивності є подання в динамічному режимі.

(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
це правда , але, безумовно, те, що ви хочете dynamic
профайлювати,

@MarcGravell Я повністю згоден з вами, як я також писав у відповіді.
eTomm

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.