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


179

これはおそらく些細なことですが、私はそれを行うためのより良い方法を考えることができません。C#でオブジェクトになるバリアントを返すCOMオブジェクトがあります。これを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()、この場合に使用します。

これは非常に一般的な回答であることに注意してください。ここで詳細を説明するのは良い仕事だと思いますが、遅れて来てまだ投票されていなかったので、Darren Clarkの応答に注意を向けたいと思います。とにかく、彼は「受け入れられた回答」に対する私の投票を取得し、(int)(int)(short)を推奨したり、失敗した場合は代わりに機能する可能性があることを指摘したり、デバッガーをチェックして実際のランタイムタイプを確認したりすることを推奨しています。


私は実際にはエラーではない点を見つけましたが、おそらく誰かがそれを単純化しすぎていて、誰かがそう思っているかもしれません。その文を削除し、信頼できるドキュメントへのリンクを追加しました。
Joel Coehoorn、2009

ダイレクトキャストは暗黙的な変換で機能しますか?私はそれが厳密に開梱のみを行い、他の変換は行わないという印象を受けました。
ダレンクラーク


結局のところ、それは単に箱を開けるだけではありません。それ以外の場合は、なぜそれを使用してdoubleをintにキャストできますか?
Joel Coehoorn、2009

そして、他のいくつかのことを読むと、そこに暗黙/明示が逆にあるかもしれませんが、どちらにしても、ポイントは理解できると思います。
Joel Coehoorn、2009

41

キャスト(int) myobject うまくいくはずです。

無効なキャスト例外が発生する場合は、バリアント型がVT_I4ではないことが原因である可能性があります。私の賭けは、VT_I4を持つバリアントはボックス化されたintに変換され、VT_I2はボックス化されたshortに変換されるなどです。

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

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


32

Convert.ToInt32(myobject);

これは、例外をスローする代わりに、myobjectがnullで0を返す場合を処理します。


このようにしようとすると、「シンボル 'ToInt'を解決できません」と表示されます。たとえばを使用した場合にのみ機能しますToInt32
Tobias Feil

この方法はどこにありますか?.Net Frameworkライブラリにありますか?
Amir Pourmandامیرپورمند19年

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では、バリアントを文字列に変換する必要があります。私の知る限り、問題は文字列から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。OPには完璧な答えではないかもしれませんが、それは間違いなくいくつかの人に役立ちます!
PhilippeParé2017年

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

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

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

代わりに別の単純な方法ですが、実際のパフォーマンスコストは、前に動的にキャストすることです。

(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
これは本当ですが、多くの場合、dynamic
プロファイリングし

@MarcGravell回答にも書いたように、私はあなたに完全に同意します。
eTomm 2019

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.