将对象转换为int的更好方法


179

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

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

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

Answers:


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

直接转换是否可以使用隐式转换?我给人的印象是,这将严格只取消装箱,而不进行任何其他转换。
达伦·克拉克

:不完全是一个回应,但阅读这blogs.msdn.com/ericlippert/archive/2009/03/19/...
乔尔Coehoorn

结果是,它肯定不只是取消装箱。否则,为什么要使用它例如将双精度类型转换为int?
Joel Coehoorn

在阅读其他内容时,我可能会将我的隐式/显式倒退到其他地方,但是无论哪种方式,我都认为这很有意义。
Joel Coehoorn

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'”。仅当我使用eg时才有效ToInt32
Tobias Feil

在哪里可以找到这种方法?在.Net Framework库中吗?
阿米尔·普尔曼德

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");
  }

实际上,如果TryParse返回false,则Parse调用TryParse并引发异常。所以TryParse不处理该异常,因为它从不抛出异常。
塞缪尔

从技术上讲,它们都调用相同的NumberToInt32方法,但是只有Parse在不起作用时才会引发异常。
塞缪尔

TryParse仍然需要将变体转换为字符串。AFAIK的问题不是从字符串转换为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的完美答案,但这绝对对某些人有帮助!
菲利普·帕雷

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

奇怪,但是关于强制转换和转换的答案似乎是错误的,这意味着从我的测试和阅读文档中也不应考虑隐式或显式运算符。

因此,如果我有一个object类型的变量,并且“ boxed”类定义了一些隐式运算符,则它们将无法工作。

取而代之的是另一种简单的方法,但真正的性能成本计算是动态进行的。

(int)(动态)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是远离自由
马克·Gravell

@MarcGravell我完全同意你的看法,正如我也在答案中所写。
eTomm

0
int i = myObject.myField.CastTo<int>();
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.