Переопределение унаследованных универсальных методов - PullRequest
25 голосов
/ 20 апреля 2010

У меня есть этот код в базовом классе

 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 ]

43 голосов
/ 20 апреля 2010

Вы не можете переопределить параметр типа универсального метода в производном классе. Для достижения аналогичной функциональности, один из вариантов состоит в том, чтобы ваш базовый класс был универсальным и имел ваш производный класс, такой как

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 неуниверсальный метод.

2 голосов
/ 09 августа 2016

Подобно ответу Джона Карпентера, вы можете переопределить универсальный метод с помощью того же универсального метода, но просто используйте оператор 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
}
0 голосов
/ 11 мая 2016

У меня был тот же вариант использования, который вы искали. В базовом классе есть универсальный метод, и я хочу переопределить метод только для одного типа. Для всех других типов я хотел, чтобы метод вел себя так же. Вот простой пример, основанный на вашем вопросе.

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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...