Cara yang lebih baik untuk melemparkan objek ke int

179

Ini mungkin sepele, tetapi saya tidak bisa memikirkan cara yang lebih baik untuk melakukannya. Saya memiliki objek COM yang mengembalikan varian yang menjadi objek di C #. Satu-satunya cara saya bisa mendapatkan ini menjadi int adalah

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

Apakah ada cara yang lebih bersih untuk melakukan ini? Terima kasih

Steve
sumber

Jawaban:

362

Anda memiliki beberapa opsi:

  • (int)- Operator cor. Berfungsi jika objek sudah bilangan bulat pada tingkat tertentu dalam hierarki warisan atau jika ada konversi implisit yang ditentukan.

  • int.Parse()/int.TryParse() - Untuk mengkonversi dari serangkaian format yang tidak dikenal.

  • int.ParseExact()/int.TryParseExact() - Untuk mengkonversi dari string dalam format tertentu

  • Convert.ToInt32() - Untuk mengonversi objek dari tipe yang tidak dikenal. Ini akan menggunakan konversi eksplisit dan implisit atau implementasi IConvertible jika ada yang didefinisikan.

  • as int?- Perhatikan "?". The asoperator adalah hanya untuk referensi jenis, dan jadi saya menggunakan "?" untuk menandakan a Nullable<int>. Operator " as" bekerja seperti Convert.To____(), tetapi pikirkan TryParse()daripada Parse(): itu mengembalikan nulldaripada melemparkan pengecualian jika konversi gagal.

Dari jumlah tersebut, saya lebih suka (int)jika objeknya benar-benar hanya bilangan bulat kotak. Kalau tidak gunakan Convert.ToInt32()dalam kasus ini.

Perhatikan bahwa ini adalah jawaban yang sangat umum : Saya ingin memberi perhatian pada respons Darren Clark karena saya pikir ini merupakan pekerjaan yang baik untuk menangani hal-hal spesifik di sini, tetapi datang terlambat dan belum juga memilih. Dia mendapatkan suara saya untuk "jawaban yang diterima", bagaimanapun, untuk juga merekomendasikan (int), untuk menunjukkan bahwa jika gagal (int)(short)mungkin bekerja sebagai gantinya, dan untuk merekomendasikan Anda memeriksa debugger Anda untuk mengetahui jenis runtime yang sebenarnya.

Joel Coehoorn
sumber
Saya memang menemukan titik yang tidak benar-benar kesalahan tetapi mungkin hal-hal yang disederhanakan terlalu banyak sehingga seseorang mungkin berpikir begitu. Saya telah menghapus kalimat itu dan menambahkan tautan ke dokumentasi otoritatif.
Joel Coehoorn
Akankah para pemeran langsung bekerja dengan konversi tersirat? Saya mendapat kesan bahwa itu hanya akan melakukan unboxing, bukan konversi lainnya.
Darren Clark
Bukan jawaban yang pasti, tetapi baca ini: blogs.msdn.com/ericlippert/archive/2009/03/19/…
Joel Coehoorn
Hasilnya adalah bahwa ia pasti melakukan lebih dari sekadar membuka kotak. Kalau tidak, mengapa Anda bisa menggunakannya untuk melemparkan dobel ke int, misalnya?
Joel Coehoorn
Dan membaca beberapa hal lain, saya mungkin memiliki implisit / eksplisit saya mundur di sana - tetapi baik cara saya pikir itu intinya.
Joel Coehoorn
41

Para pemain (int) myobject seharusnya hanya bekerja.

Jika itu memberi Anda pengecualian pemain yang tidak valid maka itu mungkin karena jenis varian bukan VT_I4. Taruhan saya adalah bahwa varian dengan VT_I4 dikonversi menjadi kotak int, VT_I2 menjadi kotak pendek, dll.

Ketika melakukan gips pada tipe nilai kotak, itu hanya berlaku untuk melemparkannya ke tipe kotak. Misalnya musuh, jika varian yang dikembalikan sebenarnya adalah VT_I2 maka(int) (short) myObject harus berfungsi.

Cara termudah untuk mengetahuinya adalah dengan memeriksa objek yang dikembalikan dan melihat tipenya di debugger. Juga pastikan bahwa dalam unit interop Anda memiliki nilai kembali yang ditandaiMarshalAs(UnmanagedType.Struct)

Darren Clark
sumber
32

Convert.ToInt32 (objek saya);

ini akan menangani kasus di mana objek saya adalah nol dan mengembalikan 0, alih-alih melemparkan pengecualian.

Zahir J
sumber
Saya mendapatkan "Tidak dapat menyelesaikan simbol 'ToInt'" ketika saya mencobanya seperti ini. Ini hanya berfungsi jika saya menggunakan mis ToInt32.
Tobias Feil
Di mana kita dapat menemukan metode ini? Apakah itu di .Net Framework Library?
Amir Pourmand امیر پورمند
8

Gunakan Int32.TryParsesebagai berikut.

  int test;
  bool result = Int32.TryParse(value, out test);
  if (result)
  {
     Console.WriteLine("Sucess");         
  }
  else
  {
     if (value == null) value = ""; 
     Console.WriteLine("Failure");
  }
Srikar Doddi
sumber
Sebenarnya, Parse memanggil TryParse dan melempar pengecualian jika TryParse mengembalikan false. Jadi TryParse tidak menangani pengecualian karena tidak pernah melempar satu.
Samuel
Yah secara teknis mereka berdua memanggil metode yang sama NumberToInt32, tetapi hanya Parse melempar pengecualian ketika itu tidak berhasil.
Samuel
TryParse masih membutuhkan konversi varian menjadi string. AFAIK masalah tidak mengkonversi dari string ke int, tetapi dari varian yang int ke int sebenarnya.
Darren Clark
3

Saya mencantumkan perbedaan dalam setiap cara casting. Apa jenis penanganan casting tertentu dan tidak?

    // 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
    }
Subramanian Naya
sumber
2

Mungkin Convert.ToInt32 .

Perhatikan pengecualian, dalam kedua kasus.

JW
sumber
2
var intTried = Convert.ChangeType(myObject, typeof(int)) as int?;
Tohid
sumber
1
Saya menemukan jawaban ini sangat berguna, saya ingin memasukkan byte kotak ke int, dan mulai menggunakannya Convert.ChangeType. Saya akan mengatakan mungkin bukan jawaban yang sempurna untuk OP, tetapi pasti membantu beberapa orang!
Philippe Paré
1

Ada juga TryParse .

Dari 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);
      }
   }
Lance Harper
sumber
1

Aneh, tetapi jawaban yang diterima tampaknya salah tentang para pemeran dan Konversi dalam arti bahwa dari tes saya dan membaca dokumentasi juga tidak boleh memperhitungkan operator implisit atau eksplisit akun.

Jadi, jika saya memiliki variabel tipe objek dan kelas "kotak" memiliki beberapa operator implisit yang ditentukan mereka tidak akan bekerja.

Alih-alih cara sederhana lain, tetapi sebenarnya biaya kinerja adalah untuk melakukan sebelumnya secara dinamis.

(int) (dinamis) myObject.

Anda dapat mencobanya di jendela Interaktif 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
eTomm
sumber
1
ini benar , tetapi jelas sesuatu yang ingin Anda profil jika Anda sering melakukannya - dynamicjauh dari gratis
Marc Gravell
@ Marccravell Saya sangat setuju dengan Anda, karena saya juga menulis dalam jawabannya.
eTomm
0
int i = myObject.myField.CastTo<int>();
Tidak
sumber