flutterdartgenericsgeneric-method

Dart generics method not recognizing type


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


Solution

  • 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.