将“this”强制转换为类型参数¶
ID: cs/cast-of-this-to-type-parameter
Kind: problem
Security severity:
Severity: recommendation
Precision: high
Tags:
- reliability
- maintainability
- language-features
Query suites:
- csharp-security-and-quality.qls
将 this
强制转换为类型参数可能表示隐式类型约束。也就是说,程序员想要表达 this
可以转换为类型参数,但找不到合适的表达方式。因此,他们依赖派生类型来实现正确的接口。
建议¶
解决方案是使用基类型上的抽象属性机制来强制执行约束。然后,每个派生类型都必须实现此属性,这使得编译器可以检查约束,并消除了强制转换的需要。
示例¶
在此示例中,程序员依赖于 BaseNode
的任何具体实现来遵循正确的设
class CastThisToTypeParameter
{
abstract class BaseNode<T> where T : BaseNode<T>
{
public abstract T Parent { get; }
public T Root
{
get
{
T cur = (T)this;
while (cur.Parent != null)
{
cur = cur.Parent;
}
return cur;
}
}
}
class Derived1 : BaseNode<Derived1>
{
private string name;
private Derived1 parent;
public Derived1(string name, Derived1 parent)
{
this.name = name;
this.parent = parent;
}
public override Derived1 Parent { get { return parent; } }
}
class Derived2 : BaseNode<Derived1>
{
private string name;
private Derived1 parent;
public Derived2(string name, Derived1 parent)
{
this.name = name;
this.parent = parent;
}
public override Derived1 Parent { get { return parent; } }
}
}
最好使用抽象属性来强制执行此操作。
class CastThisToTypeParameterFix
{
abstract class BaseNode<T> where T : BaseNode<T>
{
public abstract T Self { get; }
public abstract T Parent { get; }
public T Root
{
get
{
T cur = Self;
while (cur.Parent != null)
{
cur = cur.Parent;
}
return cur;
}
}
}
class ConcreteNode : BaseNode<ConcreteNode>
{
private string name;
private ConcreteNode parent;
public ConcreteNode(string name, ConcreteNode parent)
{
this.name = name;
this.parent = parent;
}
public override ConcreteNode Self { get { return this; } }
public override ConcreteNode Parent { get { return parent; } }
}
}