【问题标题】:IS vs. AS vs. IsAssignableFrom - What are the differences when checking for objectTypes and Interfaces?IS vs. AS vs. IsAssignableFrom - 检查 objectTypes 和 Interfaces 时有什么区别?
【发布时间】:2015-05-29 12:06:13
【问题描述】:

我对 C# 有点陌生,我想知道你是否可以帮助我。

场景:

public bool ObjectImplementsSpecificInterface (object obj)
{
    // 1.
    if (obj is IExampleInterface) 
    {
        return true;
    }

    // 2.
    var tmp = obj as IExampleInterface;
    if (tmp != null) 
    {
        return true;
    }

    // 3.
    if (typeof(IExampleInterface).IsAssignableFrom (obj.GetType ())) 
    {
        return true;
    }
}

目标:确定对象是否实现给定的接口定义IExampleInterface

问题:

  • 哪种实现是最佳实践?
  • 忽略第一个问题,哪一个在技术上最正确?
  • 运营商的具体区别是什么? MSDNAA 并未真正详细说明它们。
  • 哪个通话时间最长/最短?

【问题讨论】:

  • 当您需要更多价值时,请使用 is 构造(变体 1)或 as(变体 2)。
  • 我无法想象这里以前没有介绍过。
  • 我也是这么想的,但我只能找到谈论特定运营商的答案,而不是相互比较。如果您找到一个回答我的问题的线程,请随时链接它! :)
  • 4:typeof(IExampleInterface).IsInstanceOfType(obj)。在调用obj.GetType() 之前,您应该检查obj 是否为空。

标签: c# performance object interface operators


【解决方案1】:

所有三种方法都将提供相同的结果,并且所花费的时间大致相同,但只有第一种是专门针对您的情况而设计的。

当您从一个对象开始,并且您只需要知道它的类是否实现给定接口时,第一种方法(即is 运算符)是最合适的。

第二种方法适用于需要确定一个对象是否是接口的实现的情况,并且在将其转换为接口后也使用该对象。如果您打算在null-检查之后丢弃转换结果,那么首先执行转换是没有意义的。

第三种方法主要用于反射,当您有一个 System.Type 对象而不是对象本身时。

【讨论】:

  • 第三种方法主要用于反射,当你有一个 System.Type 对象而不是对象本身时。 即使对于泛型它也有一些用途......
【解决方案2】:

“Is”运算符允许您检查特定实例是否属于特定类型或继承此类型,而 IsAssignableFrom 允许您检查一个类型是否可转换为另一个类型。

因此,如果您遇到必须评估某个对象是否属于特定类型的情况,那么您使用的是:

Random r = new Random();
if (r is Random)
{
    reutrn true;
}

但是如果你只有这样的类型:

public bool CheckIfTypeIsRandom(Type typeKnownAtRuntime)
{
     if (typeof(Random).IsAssignableFrom(typeKnownAtRuntime) 
     {
         return true;
     }
     return false;
}

那么你必须使用 IsAssignableFrom。

【讨论】:

    【解决方案3】:

    从以下帖子中收集到的信息和可能正确的答案如下:

    运营商is

    • 应该用于确定对象是实现接口还是属于特定类型,所以这是我问题的答案:最佳实践是哪一个?

    运营商as

    • 应该比is花费更长的时间。
    • 通常用于将对象存储到将表示正确类型的var 中。
    • 用于进一步处理对象。调用函数或检查接口类型。

    运营商isAssignableFrom

    • 检查对象是否可以转换为另一种类型。
    • 如果对象的类型在运行时未知,则应使用。

    【讨论】:

      【解决方案4】:
      1. var impInterface = obj is ISampleInterface;
      2. “技术上”是什么意思?他们都工作。如果您只想让ois 知道它是否实现了接口,那就是is 的用途。如果您想要一个转换为接口的新变量,请使用as
      3. is 确定对象是否派生自一个类型并返回一个布尔值。 as 尝试将对象转换为类型,并将转换为类型的新变量返回,如果不能,则返回 null。 (但你从你的问题中知道这一点)。
      4. as 可能需要更长的时间,即使演员阵容有效。

      【讨论】:

      • 这里是上述评论的参考:msdn.microsoft.com/en-us/library/cscsdfbt.aspx我正要发布同样的内容。
      • 技术上从最尖锐的角度出发。因此,在查看 c# 的工作原理时,基本上该走哪一个操作系统。
      • 我对“c-Sharp-ish”是什么意思感到头疼。显然它们都是 C#。哪一个是“可行的方法”取决于您要执行的操作,确定变量是指派生自某个指定类型的对象,还是将其强制转换为该类型。仅此而已。
      【解决方案5】:

      1) 如果您只是想检查一个对象是否属于某个类型或实现了某个接口,请使用is

      2) 如果你想检查类型或接口并对对象做一些事情,请使用as。所以而不是:

      if (obj is A) {
          A casted = (A) obj;
          casted.MethodOfA ();
      }
      

      你应该这样做

      A casted = obj as A
      if (casted != null) {
          casted.MethodOfA ();
      }
      

      3) 仅在 1) 不可用时使用此方法,例如您将类型作为 Type 类型的对象,而不是 T

      【讨论】:

      • 糟糕,我的错。不,反射不参与其中。
      猜你喜欢
      • 1970-01-01
      • 2011-05-23
      • 1970-01-01
      • 2012-05-21
      • 2022-08-17
      • 2014-07-01
      • 2021-07-16
      • 2013-03-18
      相关资源
      最近更新 更多