错失使用 Cast 的机会¶
ID: cs/linq/missed-cast
Kind: problem
Security severity:
Severity: recommendation
Precision: high
Tags:
- maintainability
- language-features
Query suites:
- csharp-security-and-quality.qls
当你迭代一个已知只包含另一种类型(可能是更具体的类型)元素的集合时,通常会使用强制转换。例如,List<Animal> >
可能引用 Dog
的实例集合,Dog
是从 Animal
派生的类。程序员经常编写循环来迭代集合,并在使用之前将每个 Animal
依次强制转换为 Dog
建议¶
此模式效果很好,并且在 LINQ 中也作为 Cast
方法提供。除非你需要自定义版本,否则最好使用库方法,而不是编写自己的模式。特别是,这可以通过更好地表达意图和减少循环范围内不同变量的数量来提高代码的可读性。重要的是要记住,如果任何元素无法强制转换,Cast 将引发 InvalidCastException。(如果你不确定所有元素是否都具有预期类型,并且你只想对具有预期类型的元素进行操作,请考虑改用 OfType
。)
示例¶
在本例中,Animal
数组中的每个元素都被强制转换为 Dog
。
class MissedCastOpportunity
{
class 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 Dog("Fido"), new Dog("Basil") };
foreach (Animal a in lst)
{
Dog d = (Dog)a;
d.Woof();
}
}
}
可以使用 LINQ 的 cast 方法更好地编写此代码,以强制转换整个列表,然后对其进行迭代。
class MissedCastOpportunityFix
{
class 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 Dog("Fido"), new Dog("Basil") };
foreach (Dog d in lst.Cast<Dog>())
{
d.Woof();
}
}
}