错失使用 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
程序员经常使用 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();
}
}
}