Подтвердить что ты не робот

Переопределение унаследованных общих методов

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

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

В классе child я переопределяю

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

Я получаю эту ошибку

'' 'Объявление параметра типа должно быть идентификатором, а не типом' ''

Что я здесь делаю неправильно?

4b9b3361

Ответ 1

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

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

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

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

Ответ 3

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