Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invoke method on generic type?

Why does the following generate an error in Delphi (XE)?

unit UTest;

interface


type

TTest = class
  public
  procedure Foo<T>(A: T);
end;

implementation

{ TTest }

procedure TTest.Foo<T>(A: T);
begin
  A.Add('hej');
end;

end.

I thought that generic types in Delphi was simply inserted into the generic function, so it would only error out if used with a type which don't have an Add(string) method.

like image 810
monoceres Avatar asked Aug 26 '13 14:08

monoceres


People also ask

How do you invoke a generic method?

To call a generic method, you need to provide types that will be used during the method invocation. Those types can be passed as an instance of NType objects initialized with particular . NET types.

Can you directly invoke generic method using .NET reflection?

Luckily, this is quite easy to do with the help of reflection. The first step to dynamically invoking a generic method with reflection is to use reflection to get access to the MethodInfo of the generic method. To do that simply do this: var methodInfo = typeof(ClassWithGenericMethod).

How do I use reflection to call a generic method?

You need to use reflection to get the method to start with, then "construct" it by supplying type arguments with MakeGenericMethod: MethodInfo method = typeof(Sample). GetMethod(nameof(Sample. GenericMethod)); MethodInfo generic = method.

What is invoke method in C#?

Dynamically invokes a method whose name and parameters must be set at run time. The Invoke( ) method is one of several reflection methods of the Progress. Lang. Class class that provide type information about a class or interface at run time.


1 Answers

Your code produces a compilation error because the compiler has no way of knowing that T has a method named Add that receives a single string parameter.

I thought that generic types in Delphi was simply inserted into the generic function, so it would only error out if used with a type which don't have an Add(string) method.

If you were using Smalltalk or C++ templates, then your assumption would be accurate. However, generics are not the same as templates. For generics you need to apply a constraint to the type parameter. The constraint needs to tell the compiler what properties T must have.

For example, you could constrain T to be derived from a class that has a suitable Add method. Or you could constrain T to implement an interface with a suitable Add method.

Documentation link for Delphi generic constraints: http://docwiki.embarcadero.com/RADStudio/en/Constraints_in_Generics

The generic constraints that can be applied are rather limited, which is something of a shame. For example, I'd love to be able to constrain a type to have certain mathematical operators. For example, I'd like to be able to constrain a type to have + and - operators, say. However, there are pros and cons to both generics and templates, and so I do accept that these limitations are the result of a justifiable design decision by the Delphi language designers.

like image 135
David Heffernan Avatar answered Sep 20 '22 00:09

David Heffernan