Even without generics, you can have different delegate types that are identical in signatures and return types. For example:
namespace N
{
// Represents a method that takes in a string and checks to see
// if this string has some predicate (i.e. meets some criteria)
// or not.
internal delegate bool StringPredicate(string stringToTest);
// Represents a method that takes in a string representing a
// yes/no or true/false value and returns the boolean value which
// corresponds to this string
internal delegate bool BooleanParser(string stringToConvert);
}
In the above example, the two non-generic types have the same signature and return type. (And actually also the same as Predicate<string>
and Func<string, bool>
). But as I tried to indicate, the "meaning" of the two are different.
This is somewhat like if I make two classes, class Car { string Color; decimal Price; }
and class Person { string FullName; decimal BodyMassIndex; }
, then just because both of them hold a string
and a decimal
, that doesn't mean they're the "same" type.