C# 将对象强制转换为 int 的更好方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/745172/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 23:32:24  来源:igfitidea点击:

Better way to cast object to int

c#interop

提问by Steve

This is probably trivial, but I can't think of a better way to do it. I have a COM object that returns a variant which becomes an object in C#. The only way I can get this into an int is

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

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

Is there a cleaner way to do this? Thanks

有没有更干净的方法来做到这一点?谢谢

采纳答案by Joel Coehoorn

You have several options:

您有多种选择:

  • (int)— Cast operator. Works if the object already isan integer at some level in the inheritance hierarchy or if there is an implicit conversion defined.

  • int.Parse()/int.TryParse()— For converting from a string of unknown format.

  • int.ParseExact()/int.TryParseExact()— For converting from a string in a specific format

  • Convert.ToInt32()— For converting an object of unknown type. It will use an explicit and implicit conversion or IConvertible implementation if any are defined.

  • as int?— Note the "?". The asoperator is only for reference types, and so I used "?" to signify a Nullable<int>. The "as" operator works like Convert.To____(), but think TryParse()rather than Parse(): it returns nullrather than throwing an exception if the conversion fails.

  • (int)— 转换运算符。如果对象已经是继承层次结构中某个级别的整数,或者定义了隐式转换,则有效。

  • int.Parse()/int.TryParse()— 用于从未知格式的字符串转换。

  • int.ParseExact()/int.TryParseExact()— 用于从特定格式的字符串转换

  • Convert.ToInt32()— 用于转换未知类型的对象。如果已定义,它将使用显式和隐式转换或 IConvertible 实现。

  • as int?— 请注意“?”。该as操作仅作参考类型,所以我用“?” 表示一个Nullable<int>。" as" 运算符的工作方式类似于Convert.To____(),但要考虑TryParse()而不是Parse()null如果转换失败,它会返回而不是抛出异常。

Of these, I would prefer (int)if the object really is just a boxed integer. Otherwise use Convert.ToInt32()in this case.

其中,(int)如果对象真的只是一个装箱整数,我更愿意。否则Convert.ToInt32()在这种情况下使用。

Note that this is a very generalanswer: I want to throw some attention to Darren Clark's response because I think it does a good job addressing the specificshere, but came in late and wasn't voted as well yet. He gets my vote for "accepted answer", anyway, for also recommending (int), for pointing out that if it fails (int)(short)might work instead, and for recommending you check your debugger to find out the actual runtime type.

请注意,这是一个非常笼统的答案:我想对 Darren Clark 的回应给予一些关注,因为我认为它在解决这里的具体细节方面做得很好,但迟到了,而且还没有被投票。无论如何,他得到了我对“接受的答案”的投票,因为他也推荐 (int),指出如果失败(int)(short)可能会起作用,并建议您检查调试器以找出实际的运行时类型。

回答by J.W.

Maybe Convert.ToInt32.

也许Convert.ToInt32

Watch out for exception, in both cases.

在这两种情况下都要注意异常。

回答by Srikar Doddi

Use Int32.TryParseas follows.

使用Int32.TryParse如下。

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

回答by Zahir J

Convert.ToInt32(myobject);

Convert.ToInt32(myobject);

this will handle the case where myobject is null and return 0, instead of throwing an exception.

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

回答by Lance Harper

There's also TryParse.

还有TryParse

From MSDN:

来自 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);
      }
   }

回答by Darren Clark

The cast (int) myobjectshouldjust work.

演员阵容(int) myobject应该可以正常工作。

If that gives you an invalid cast exception then it is probably because the variant type isn't VT_I4. My bet is that a variant with VT_I4 is converted into a boxed int, VT_I2 into a boxed short, etc.

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

When doing a cast on a boxed value type it is only valid to cast it to the type boxed. Foe example, if the returned variant is actually a VT_I2 then (int) (short) myObjectshould work.

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

Easiest way to find out is to inspect the returned object and take a look at its type in the debugger. Also make sure that in the interop assembly you have the return value marked with MarshalAs(UnmanagedType.Struct)

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

回答by Tohid

var intTried = Convert.ChangeType(myObject, typeof(int)) as int?;

回答by Nayas Subramanian

I am listing the difference in each of the casting ways. What a particular type of casting handles and it doesn't?

我列出了每种铸造方式的差异。什么特殊类型的铸造手柄,它没有?

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

回答by eTomm

Strange, but the accepted answer seems wrong about the cast and the Convert in the mean that from my tests and reading the documentation too it should not take into account implicit or explicit operators.

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

So, if I have a variable of type object and the "boxed" class has some implicit operators defined they won't work.

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

Instead another simple way, but really performance costing is to cast before in dynamic.

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

(int)(dynamic)myObject.

(int)(dynamic)myObject.

You can try it in the Interactive window of VS.

您可以在 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

回答by Nae

int i = myObject.myField.CastTo<int>();