web-dev-qa-db-ja.com

オブジェクトをintにキャストするより良い方法

これはおそらく些細なことですが、それを行うより良い方法は考えられません。 C#のオブジェクトになるバリアントを返すCOMオブジェクトがあります。これをintに入れることができる唯一の方法は

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

これを行うよりクリーンな方法はありますか?ありがとう

152
Steve

いくつかのオプションがあります:

  • (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)(short)が動作する可能性があることを指摘し、デバッガーを確認して実際のランタイムタイプを確認することを推奨するために、彼は「受け入れられた答え」に投票します。

322
Joel Coehoorn

キャスト(int)myobjectshouldは正常に機能します。

無効なキャスト例外が発生する場合は、おそらくバリアント型がVT_I4ではないためです。私の賭けは、VT_I4を持つバリアントがボックス化されたintに、VT_I2がボックス化されたshortに変換される、などです。

ボックス化された値の型でキャストを行う場合、ボックス化された型にキャストすることのみが有効です。たとえば、返されたバリアントが実際にVT_I2である場合、(int)(short)myObjectは機能するはずです。

見つける最も簡単な方法は、返されたオブジェクトを検査し、デバッガでそのタイプを調べることです。また、相互運用機能アセンブリで、戻り値がMarshalAs(UnmanagedType.Struct)でマークされていることを確認してください。

35
Darren Clark
Convert.ToInt(myobject);

これは、myobjectnullであるケースを処理し、例外をスローする代わりに0を返します。

24
Zahir J

次のようにInt32.TryParseを使用します。

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

各キャスト方法の違いをリストしています。キャストの特定のタイプは何を処理しますか?

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

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);
      }
   }
2
Lance Harper

奇妙ですが、キャストと変換について受け入れられた答えは間違っているようです。つまり、私のテストとドキュメントを読むことから、暗黙的または明示的な演算子を考慮に入れてはいけません。

したがって、オブジェクト型の変数があり、「ボックス化」クラスに暗黙的な演算子が定義されている場合、それらは機能しません。

代わりに別の簡単な方法がありますが、実際にパフォーマンスを犠牲にすることは、以前に動的にキャストすることです。

(int)(dynamic)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
eTomm

多分 Convert.ToInt32

どちらの場合も例外に注意してください。

1
J.W.