CodeQL 文档

错失使用 OfType 的机会

ID: cs/linq/missed-oftype
Kind: problem
Security severity: 
Severity: recommendation
Precision: high
Tags:
   - maintainability
   - language-features
Query suites:
   - csharp-security-and-quality.qls

点击查看 CodeQL 代码库中的查询

程序员经常使用 as 来迭代包含某种类型元素的集合,该集合中可能包含其他类型(可能是更具体的类型)的元素。例如,<B> 可能指的是一个对象集合,其中一些对象引用了 D 的实例,D 是从 B 派生的类。程序员经常编写循环来迭代集合,并在使用每个 B 之前将其强制转换为 D

建议

这种模式效果很好,并且在 LINQ 中也可以作为 OfType 方法使用。除非您有特定需求需要自定义版本,否则最好使用库方法,而不是编写自己的模式。特别是,通过更好地表达意图并减少循环内作用域中不同变量的数量,这使得代码更易于阅读。

示例

在本例中,程序员只对数组中属于 Dog 类型的项感兴趣。

class MissedOfTypeOpportunity
{
    class Animal { }

    class Cat : Animal { }

    class Dog : Animal
    {
        private string name;

        public Dog(string name)
        {
            this.name = name;
        }

        public void Woof()
        {
            Console.WriteLine("Woof! My name is " + name + ".");
        }
    }

    public static void Main(string[] args)
    {
        List<Animal> lst = new List<Animal> { new Dog("Rover"), new Cat(), new Dog("Basil") };

        foreach (Animal a in lst)
        {
            Dog d = a as Dog;
            if (d != null)
                d.Woof();
        }
    }
}

使用 OfType 方法可以更好地表达这一点。

class MissedOfTypeOpportunityFix
{
    class Animal { }

    class Cat : Animal { }

    class Dog : Animal
    {
        private string name;

        public Dog(string name)
        {
            this.name = name;
        }

        public void Woof()
        {
            Console.WriteLine("Woof! My name is " + name + ".");
        }
    }

    public static void Main(string[] args)
    {
        List<Animal> lst = new List<Animal> { new Dog("Rover"), new Cat(), new Dog("Basil") };

        foreach (Dog d in lst.OfType<Dog>())
        {
            d.Woof();
        }
    }
}

参考资料

  • ©GitHub 公司
  • 条款
  • 隐私