skip to Main Content

I have an abstract base class validator with a method which takes a generic type as parameter.
I will be passing generic type parameter to base class from the subclass inheriting the base class.

Base Class:

abstract class BaseValidator {
   bool isValid<T>(T obj);
}

Child Class:

class IPv4Validator extends BaseValidator{

  final IPV4_REGEX = "^((25[0-5]|(2[0-4]|1d|[1-9]|)d).?b){4}$";

  @override
  bool isValid<String>(String obj) {
    bool hasMatch = RegExp(IPV4_REGEX).hasMatch(obj);
    return hasMatch;
  }

}

Here hasMatch takes in non nullable string. When I directly pass some string hasMatch doesn’t throw an error.
But when I try to pass the generic value in the method parameter, it shows an error.

The argument type ‘String’ can’t be assigned to the parameter type
‘String’.

I couldn’t able to understand why generic type is not accepting, even though its compile-time type.

enter image description here

2

Answers


  1. The following code solves this particular problem. But it may be different from what you intended to implement. On the other hand, the code will be cleaner if you create a new concrete class for different data types.

    abstract class BaseValidator<T> {
      bool isValid(T obj);
    }
    
    class IPv4Validator extends BaseValidator<String>{
      final IPV4_REGEX = "^((25[0-5]|(2[0-4]|1d|[1-9]|)d).?b){4}$";
    
      @override
      bool isValid(String obj) {
        bool hasMatch = RegExp(IPV4_REGEX).hasMatch(obj);
    
        return hasMatch;
      }
    }
    

    Explanation.
    In the line class IPv4Validator extends BaseValidator<String> we are not declaring a new class BaseValidator, it is already declared as BaseValidator<T>. Here we are inheriting the specialization of the existing generic class BaseValidator. While in the line bool isValid<String>(String obj), we declare a new function, so the compiler understands it as if we were declaring a new generic function with a parameter type named String. So, here bool isValid<String>(String obj) is equivalent to bool isValid<T>(T obj), just instead of name T we used name String, which is not an object String.

    Login or Signup to reply.
  2. another fix that you can do is to use the covariant keyword, to implement that, try this:

    abstract class BaseValidator<T> {
      bool isValid(T obj);
    }
    
    class IPv4Validator extends BaseValidator {
      final IPV4_REGEX = "^((25[0-5]|(2[0-4]|1d|[1-9]|)d).?b){4}$";
    
      @override
      bool isValid(covariant String obj) {
        bool hasMatch = RegExp(IPV4_REGEX).hasMatch(obj);
        return hasMatch;
      }
    }
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search