CodeQL 文档

将“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

点击查看 CodeQL 存储库中的查询

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; } }
    }
}
  • ©GitHub 公司
  • 条款
  • 隐私