覆盖继承的泛型方法

时间:2010-04-20 16:40:55

标签: c# generics

我在基类中有这段代码

 protected virtual bool HasAnyStuff<TObject>(TObject obj) where TObject:class 
  {
      return false;
  }

在儿童班,我压倒了

protected override bool HasAnyStuff<Customer>(Customer obj) 
  {
    //some stuff
      if Customer.sth etc
      return false;
  }

我收到此错误

  

'''类型参数声明必须是标识符,而不是类型'''

我在这里做错了什么?

3 个答案:

答案 0 :(得分:43)

您不能在派生类中覆盖泛型方法的类型参数。要实现类似的功能,一个选项是让你的基类成为泛型类,并拥有你的派生类,如

class Derived : BaseClass<Customer>
{
     protected override bool HasAnyStuff(Customer customer)
     {
         // ...
     }
}

其中BaseClass被声明为

class BaseClass<T> where T : class
{
    // ...
    protected virtual bool HasAnyStuff(T obj)
    {
         // ...
    }
}

或者,根据您的派生类的确切使用方式,您可以使用非泛型HasAnyStuff参数覆盖Customer方法。

public bool HasAnyStuff(Customer customer)
{
    // ...
}

但请注意,如果您不使用HasAnyStuff的实例,则不会调用新的DerivedClass。也就是说,

BaseClass foo = new DerivedClass();
foo.HasAnyStuff(new Customer());

会调用BaseClass的通用方法,而不是DerivedClass的非通用方法。

答案 1 :(得分:2)

与John Carpenter的答案类似,您可以使用相同的泛型方法覆盖泛型方法,但只需使用as运算符检查并将其强制转换为所需类型。这具有使用空值测试来检查转换是否有效的额外好处。

基类

protected virtual bool HasAnyStuff<TObject>(TObject obj)
{
    .... // base implementation
}

继承类

protected override bool HasAnyStuff<TObject>(TObject obj)
{
    var customer = obj as Customer;
    if (customer == null) // conversion failed. object is not of type Customer
    {
        return base.HasAnyStuff(obj);
    }

    .... // do stuff with the customer
}

答案 2 :(得分:0)

我有同样的用例你正在寻找。基类上有一个泛型方法,我想只覆盖一个类型的方法。对于所有其他类型,我希望该方法的行为方式相同。这是一个基于您的问题的简单示例。

class BaseClass
{
    protected virtual bool HasAnyStuff<TObject>(TObject obj)
    {
        return false;
    }
}

class DerivedClass : BaseClass
{
    protected override bool HasAnyStuff<TObject>(TObject obj)
    {
        if (typeof(TObject) != typeof(AlarmTran)) return base.HasAnyStuff<TObject>(obj);

        //some stuff
        //if Customer.sth etc
        return false;
    }
}

您也可以反转if逻辑来处理许多不同类型的多个覆盖。

protected override bool HasAnyStuff<TObject>(TObject obj)
{
    if (typeof(TObject) == typeof(AlarmTran))
    {
        //some stuff
        //if Customer.sth etc
        return false;
    }
    else if (typeof(TObject) == typeof(...))
    {
        ...
        return ...;
    }

    return base.HasAnyStuff<TObject>(obj);
}