jess
jess

Reputation: 1207

Overriding inherited generic methods

I have this code in base class

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

In child class I am overriding

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

I am getting this error

'''Type parameter declaration must be an identifier not a type'''

What is it I am doing wrong here?

Upvotes: 43

Views: 46232

Answers (3)

Zac Faragher
Zac Faragher

Reputation: 1001

Similar to John Carpenter's answer, you can override the generic method with the same generic method, but simply use the as operator to check and cast it to the desired type. This has the added benefit of using null-testing to check if the conversion worked.

Base Class

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

Inherited Class

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
}

Upvotes: 7

Frank Bryce
Frank Bryce

Reputation: 8446

I had the same use case that you are looking for. There is a generic method on the base class and I want to override the method for just a single type. For all other types, I wanted the method to behave the same way. Here is a simple example based on your question.

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;
    }
}

You may also invert the if logic to handle multiple overrides for many different types.

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);
}

Upvotes: 0

Mark Rushakoff
Mark Rushakoff

Reputation: 258138

You can't override a generic method's type parameter in a derived class. To achieve a similar functionality, one option is to have your base class be a generic class, and have your derived class such as

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

where BaseClass is declared as

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

Alternatively, depending on exactly how your derived class is being used, you can just override the HasAnyStuff method with a non-generic Customer argument.

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

However, note that the new HasAnyStuff will not be called if you are not working with an instance of DerivedClass. That is to say,

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

will call BaseClass's generic method, not DerivedClass's non-generic method.

Upvotes: 64

Related Questions