Nesneyi int yapmanın daha iyi yolu


179

Bu muhtemelen önemsizdir, ancak bunu yapmanın daha iyi bir yolunu düşünemiyorum. C # 'da bir nesne haline gelen bir değişken döndüren bir COM nesnesi var. Bunu bir int içine almanın tek yolu

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

Bunu yapmanın daha temiz bir yolu var mı? Teşekkürler

Yanıtlar:


362

Birkaç seçeneğiniz var:

  • (int)- Döküm operatörü. Nesne eğer çalışır zaten bir tamsayı kalıtım hiyerarşisinde bazı seviyesinde veya tanımlanmış örtük dönüştürme varsa.

  • int.Parse()/int.TryParse() - Bilinmeyen biçime sahip bir dizeden dönüştürmek için.

  • int.ParseExact()/int.TryParseExact() - Bir dizeden belirli bir biçimde dönüştürmek için

  • Convert.ToInt32() - Bilinmeyen tipte bir nesneyi dönüştürmek için. Açık ve örtük bir dönüştürme veya tanımlanmışsa IConvertible uygulaması kullanacaktır.

  • as int?- "?" asOperatör referans tipleri içindir ve kullandığım bu yüzden "?" belirtmek için Nullable<int>. " as" Operatörü şöyle çalışır Convert.To____(), düşünmek TryParse()yerine düşünür Parse(): nulldönüşüm başarısız olursa bir istisna atmak yerine geri döner .

Bunlardan (int), nesnenin gerçekten sadece kutulu bir tamsayı olmasını tercih ederim . Aksi takdirde Convert.ToInt32()bu durumda kullanın .

Bunun çok genel bir cevap olduğuna dikkat edin: Darren Clark'ın cevabına biraz dikkat etmek istiyorum çünkü buradaki özelliklere değinmek için iyi bir iş çıkardığını düşünüyorum , ancak geç geldi ve henüz oy verilmedi. Yine de, "kabul edilen cevap" için oyumu alır, yine de, (int) önermek için, başarısız olursa (int)(short), işe yarayabileceğine işaret etmek ve hata ayıklayıcınızı gerçek çalışma zamanı türünü bulmak için kontrol etmek için.


Gerçekten bir hata olmayan bir nokta buldum ama belki de çok basitleştirilmiş şeyler, bu yüzden birisi bunu düşünebilir. Bu cümleyi kaldırdım ve yetkili belgelere bir bağlantı ekledim.
Joel Coehoorn

Doğrudan oyuncu seçimi örtük bir dönüşümle çalışır mı? Bunun sadece kutudan çıkarılması, diğer dönüşümleri değil.
Darren Clark

Tam olarak bir yanıt değil, ama bunu okuyun: blogs.msdn.com/ericlippert/archive/2009/03/19/…
Joel Coehoorn

Sonuç olarak, kesinlikle sadece kutudan daha fazlasını yapıyor. Aksi halde niçin bir int'e bir çifte atmak için kullanabilirsiniz?
Joel Coehoorn

Ve diğer bazı şeyleri okuduğumda dolaylı / açık geriye doğru sahip olabilirim - ama her iki şekilde de bunun mantıklı olduğunu düşünüyorum.
Joel Coehoorn

41

Dökme (int) myobject gerektiğini sadece çalışır.

Bu size geçersiz bir cast istisnası verirse, bunun nedeni büyük olasılıkla değişken türünün VT_I4 olmamasıdır. Bahse girerim, VT_I4 ile bir varyant kutulu bir int, VT_I2'yi kutulu bir kısa vb.

Kutulu bir değer türünde döküm yaparken, yalnızca kutulu türe döküm yapmak geçerlidir. Düşman örneği, döndürülen varyant aslında bir VT_I2 ise, o zaman (int) (short) myObjectçalışmalıdır.

Bulmanın en kolay yolu, döndürülen nesneyi incelemek ve hata ayıklayıcıdaki türüne bakmaktır. Ayrıca, birlikte çalışma derlemesinde döndürülen değerinMarshalAs(UnmanagedType.Struct)


32

Convert.ToInt32 (myObject);

bu, istisna atmak yerine myobject öğesinin boş olduğu ve 0 döndürdüğü durumu ele alır.


Bu şekilde denediğimde "ToInt" sembolü çözülemiyor. Sadece örn ToInt32.
Tobias Feil

Bu yöntemi nerede bulabiliriz? .Net Framework Kütüphanesi'nde mi?
Amir Pourmand امیر پورمند

8

Int32.TryParseAşağıdaki gibi kullanın .

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

Aslında, Parse TryParse öğesini çağırır ve TryParse yanlış döndürürse bir istisna atar. Bu yüzden TryParse istisnayı ele almaz çünkü asla atmaz.
Samuel

Teknik olarak her ikisi de aynı yöntemi NumberToInt32 olarak adlandırır, ancak çalışmadığında yalnızca Parse istisnalar atar.
Samuel

TryParse yine de varyantı bir dizeye dönüştürmeyi gerektirir. AFAIK sorunu bir dizeden int'e değil, int olan bir varyanttan gerçek int'e dönüşüyor.
Darren Clark

3

Her döküm yolundaki farkı listeliyorum. Ne tür bir döküm sapı var ve değil mi?

    // 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
Bu cevabı gerçekten yararlı buldum, kutu içine bayt baytını int olarak atmak istiyordum ve bunu kullanmaya başladım Convert.ChangeType. Ben OP için mükemmel bir cevap olmayabilir, ama kesinlikle bazılarına yardımcı olduğunu söyleyebilirim!
Philippe Paré

1

Ayrıca TryParse var .

MSDN'den:

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

Garip, ancak kabul edilen cevap, testlerimden ve dokümantasyonumdan da okuduğumda örtülü veya açık operatörleri hesaba katmaması gerektiği anlamına gelir.

Yani, bir nesne türü değişken varsa ve "boxed" sınıf bazı örtük işleçler varsa onlar işe yaramaz tanımlı.

Bunun yerine başka bir basit yol, ama gerçekten performans maliyeti daha önce dinamik olarak döküm yapmaktır.

(İnt) (dinamik) myObject.

VS'nin Etkileşimli penceresinde deneyebilirsiniz.

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
bu doğru , ama kesinlikle çok şey yapıyorsanız profil yapmak istediğiniz bir şey - dynamicücretsiz olmaktan çok uzak
Marc Gravell

@MarcGravell Cevapta da yazdığım için tamamen katılıyorum.
eTomm

0
int i = myObject.myField.CastTo<int>();
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.