http://nullprogram.com/blog/2014/04/01/试图用一个例子来解释 Java 的泛型不能模拟鸭子类型(duck typing):
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
, andT
will becomeObject
. SinceObject
has nocall()
method, compilation fails.
这是否意味着通过 Java 泛型,类型参数的方法仅限于 java.lang.Object
类的方法?
C# 的泛型是根据具体化而不是类型删除来实现的。 C#的泛型没有Java的泛型有上述限制吗?那么 C# 的泛型真的可以实现与 duck typing 相同的东西吗?
谢谢。
最佳答案
can C#'s generics actually achieve the same thing as duck typing?
没有。但是 C# 的泛型可以包含一个约束,其中类型参数被限制为继承或实现某些特定类型。完成后,该类型参数类型的任何表达式都将解析为受约束的类型,并且可以访问该类型的成员。
这类似于您阅读的文章中描述的extends
约束。
C# 中唯一的 duck-typing 支持是 dynamic
关键字,其中涉及 dynamic
值的表达式的最终编译被推迟到实际运行时类型已知的运行时。
相关阅读:
Trivial C# class with a generic parameter wouldn't compile for no apparent reason
Call a method of type parameter
关于java - 使用 Java 和 C# 的泛型来模拟鸭子类型(duck typing),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46270804/