【问题标题】:Better way to cast object to int将对象转换为 int 的更好方法
【发布时间】:2009-04-13 20:02:50
【问题描述】:

这可能是微不足道的,但我想不出更好的方法来做到这一点。我有一个 COM 对象,它返回一个变体,它成为 C# 中的一个对象。我可以把它变成 int 的唯一方法是

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

有没有更清洁的方法来做到这一点?谢谢

【问题讨论】:

    标签: c# interop


    【解决方案1】:

    您有多种选择:

    • (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) 可能会起作用,并建议您检查调试器以找出实际的运行时类型。

    【讨论】:

    • 我确实找到了一点,这并不是一个真正的错误,但可能过于简化了事情,所以有人可能会这么认为。我删除了那句话并添加了权威文档的链接。
    • 直接转换是否可以使用隐式转换?我的印象是,这只会严格执行拆箱,而不是任何其他转换。
    • 不完全是回复,但请阅读:blogs.msdn.com/ericlippert/archive/2009/03/19/…
    • 结果是它绝对不仅仅是拆箱。否则为什么你可以用它来将一个 double 转换为一个 int,例如?
    • 阅读其他一些内容时,我的隐式/显式可能会向后退——但无论哪种方式,我认为它都能理解。
    【解决方案2】:
    Convert.ToInt32(myobject);
    

    这将处理 myobject 为 null 并返回 0 的情况,而不是抛出异常。

    【讨论】:

    • 试试 System.Convert.ToInt32(myobject)。
    【解决方案3】:

    演员(int) myobject应该正常工作。

    如果这给您一个无效的强制转换异常,那么可能是因为变体类型不是 VT_I4。我敢打赌,带有 VT_I4 的变体被转换为盒装 int,VT_I2 被转换为盒装短裤,等等。

    当对装箱的值类型进行强制转换时,只有将其强制转换为装箱的类型才有效。 例如,如果返回的变体实际上是 VT_I2,那么 (int) (short) myObject 应该可以工作。

    最简单的找出方法是检查返回的对象并在调试器中查看它的类型。还要确保在互操作程序集中您的返回值标有MarshalAs(UnmanagedType.Struct)

    【讨论】:

      【解决方案4】:

      如下使用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。
      【解决方案5】:

      也许是Convert.ToInt32

      在这两种情况下都要注意例外情况。

      【讨论】:

        【解决方案6】:

        奇怪,但接受的答案似乎是关于演员表和转换的错误,这意味着从我的测试和阅读文档来看,它也不应该考虑隐式或显式运算符。

        所以,如果我有一个对象类型的变量,并且“装箱”类定义了一些隐式运算符,它们将不起作用。

        另一种简单但真正消耗性能的方法是在动态之前进行转换。

        (int)(动态)myObject.

        你可以在VS的Interactive窗口中试一试。

        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
        

        【讨论】:

        • 这是 true,但如果你经常这样做,绝对是你想要描述的东西 - dynamic 远非免费
        • @MarcGravell 我完全同意你的看法,正如我在答案中所写的那样。
        【解决方案7】:

        我列出了每种铸造方式的区别。什么特定类型的铸造处理而它没有处理?

            // 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
            }
        

        【讨论】:

          【解决方案8】:
          var intTried = Convert.ChangeType(myObject, typeof(int)) as int?;
          

          【讨论】:

          • 我发现这个答案非常有用,我希望将一个装箱字节转换为一个 int,并使用Convert.ChangeType 让它工作。我会说可能不是 OP 的完美答案,但它肯定对某些人有帮助!
          【解决方案9】:

          还有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);
                }
             }
          

          【讨论】:

            【解决方案10】:
            int i = myObject.myField.CastTo<int>();
            

            【讨论】:

              【解决方案11】:

              您可以先将对象转换为字符串,然后再将字符串转换为int; 例如:

              string str_myobject = myobject.ToString();
              int int_myobject = int.Parse(str_myobject);
              

              这对我有用。

              【讨论】:

                猜你喜欢
                • 2017-02-14
                • 2019-02-26
                • 2013-02-13
                • 1970-01-01
                • 2013-07-06
                • 1970-01-01
                • 1970-01-01
                • 2016-01-21
                • 2023-04-06
                相关资源
                最近更新 更多