【问题标题】:How can I check if an object is of a certain type at runtime in C#?如何在 C# 运行时检查对象是否属于某种类型?
【发布时间】:2011-03-25 00:09:48
【问题描述】:

如何在 C# 中在运行时检查对象是否属于某种类型?

【问题讨论】:

    标签: c# object types


    【解决方案1】:

    您可以使用 is 关键字。例如:

    using System; 
    
    class CApp
    {
        public static void Main()
        { 
            string s = "fred"; 
            long i = 10; 
    
            Console.WriteLine( "{0} is {1}an integer", s, (IsInteger(s) ? "" : "not ") ); 
            Console.WriteLine( "{0} is {1}an integer", i, (IsInteger(i) ? "" : "not ") ); 
        }
    
        static bool IsInteger( object obj )
        { 
            if( obj is int || obj is long )
                return true; 
            else 
                return false;
        }
    } 
    

    产生输出:

    fred is not an integer 
    10 is an integer
    

    【讨论】:

    • 我发现 is 关键字的方式未被充分利用。它更容易阅读!
    • 使用is 通常意味着两个演员,而一个就足够了。这就是为什么它不经常使用的原因。诚然,性能影响可能在 99.99% 的情况下难以察觉。
    • 根据要求,is' or GetType()' 可能是正确的解决方案。有关包括代码在内的差异的详细信息,请参阅我的答案。
    【解决方案2】:
    myobject.GetType()
    

    【讨论】:

      【解决方案3】:

      obj.GetType() 返回类型

      【讨论】:

      • 我不确定在过去的十年中我是否在 .NET 中看到过没有类型的对象... - 所以在这种情况下,为了提高效率,我会不检查 null。
      • 他的意思是:object obj = null; obj.GetType();,会抛出 NullReferenceException
      【解决方案4】:

      使用typeof 关键字:

      System.Type type = typeof(int);
      

      【讨论】:

        【解决方案5】:
        MyType myObjectType = argument as MyType;
        
        if(myObjectType != null)
        {
           // this is the type
        }
        else
        {
           // nope
        }
        

        包括空检查

        编辑:错误更正

        【讨论】:

        • 您需要将投射的结果存储在某个东西中。 MyType myType = myObject as MyType;,然后检查myType是否为空;这并不意味着myObjectMyType,它只是意味着它可以分配给它。这是一个重要的区别。
        【解决方案6】:

        我无法添加 cmets,所以我必须添加这个作为答案。请记住,根据文档 (http://msdn.microsoft.com/en-us/library/scekt9xw%28VS.80%29.aspx):

        一个 is 表达式的计算结果为 true if 提供的表达式是非空的, 并且提供的对象可以转换为 提供的类型而不引起 抛出异常。

        这与使用 GetType 检查类型不同。

        【讨论】:

          【解决方案7】:

          根据您的用例,“is”将无法按预期工作。取一个派生自类 Bar 的类 Foo。创建 Foo 类型的对象 obj。 'obj is Foo' 和 'obj is Bar' 都将返回 true。但是,如果您使用 GetType() 并与 typeof(Foo) 和 typeof(Bar) 进行比较,结果会有所不同。

          解释是here,这里有一段源代码展示了这种差异:

          using System;
          
          namespace ConsoleApp {
             public class Bar {
             }
          
             public class Foo : Bar {
             }
          
             class Program {
                static void Main(string[] args) {
                   var obj = new Foo();
          
                   var isBoth = obj is Bar && obj is Foo;
          
                   var isNotBoth = obj.GetType().Equals(typeof(Bar)) && obj.GetType().Equals(typeof(Foo));
          
                   Console.Out.WriteLine("Using 'is': " + isBoth);
                   Console.Out.WriteLine("Using 'GetType()': " + isNotBoth);
                }
             }
          }
          

          【讨论】:

            【解决方案8】:

            类型信息运算符(as, is, typeof): http://msdn.microsoft.com/en-us/library/6a71f45d(VS.71).aspx

            Object.GetType() 方法。

            请记住,您可能必须处理继承层次结构。如果你有一个像 obj.GetType() == typeof(MyClass) 这样的检查,如果 obj 是从 MyClass 派生的东西,这可能会失败。

            【讨论】:

              【解决方案9】:

              您也可以在 c# 7 (pattern matching) 中使用 switch/case

              string DoubleMe(Object o)
              {
                  switch (o)
                  {
                      case String s:
                          return s + s;
                      case Int32 i:
                          return (i + i).ToString();
                      default:
                          return "type which cannot double.";
                  }
              }
              
              void Main()
              {
                  var s= "Abc";
                  var i= 123;
                  var now = DateTime.Now;
              
                  DoubleMe(s).Dump();
                  DoubleMe(i).Dump();
                  DoubleMe(now).Dump();
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2011-09-28
                • 2010-10-31
                • 2011-09-10
                • 2012-10-02
                • 2012-06-21
                • 2011-07-13
                • 2012-01-03
                相关资源
                最近更新 更多