Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Java and C#'s generics to simulate duck typing

http://nullprogram.com/blog/2014/04/01/ tries to explain that Java's generics can't simulate duck typing with an example:

class Caller<T> {
    final T callee;
    Caller(T callee) {
        this.callee = callee;
    }
    public void go() {
        callee.call();  // compiler error: cannot find symbol call
    }
}

class Foo {
    public void call() { System.out.print("Foo"); }
}

class Bar {
    public void call() { System.out.print("Bar"); }
}

public class Main {
    public static void main(String args[]) {
        Caller<Foo> f = new Caller<>(new Foo());
        Caller<Bar> b = new Caller<>(new Bar());
        f.go();
        b.go();
        System.out.println();
    }
}

The program will fail with a compile-time error. This is the result of type erasure. Unlike C++’s templates, there will only ever be one compiled version of Caller, and T will become Object. Since Object has no call() method, compilation fails.

Does it mean that by Java generics, the methods of a type parameter are limited to the methods of class java.lang.Object?

C#'s generics is implemented in terms of reification instead of type erasure. Does C#'s generics not have the above limitation as Java's generics? So can C#'s generics actually achieve the same thing as duck typing?

Thanks.

like image 636
Tim Avatar asked Jan 29 '23 14:01

Tim


1 Answers

can C#'s generics actually achieve the same thing as duck typing?

No. But C#'s generics can include a constraint where the type parameter is restricted to inherit or implement some particular type. When that's done, any expression of the type of that type parameter is resolved as the constrained type and members from that type can be accessed.

This is similar to the extends constraint described in the article you read.

The only duck-typing support in C# is the dynamic keyword, where final compilation of expressions involving dynamic values is deferred until runtime when the actual runtime type is known.

Related reading:

Trivial C# class with a generic parameter wouldn't compile for no apparent reason
Call a method of type parameter

like image 143
Peter Duniho Avatar answered Feb 02 '23 09:02

Peter Duniho