我正在寻找一种根据对象类型分叉逻辑的安全方法。 我还没有找到如何检查对象是否属于特定的泛型类型。
class Test { static function main() { var aa = new AA<Int>(); //ERROR: Cast type parameters must be Dynamic //var a:A<Int> = cast(aa, A<Int>); //ERROR: Unexpected ) //var a:A<Int> = Std.instance(aa, A<Int>); //OK, but throw run-time exception with flash target. var a:A<Int> = cast aa; a.printName(); //Run-time exception a = cast "String is obviously wrong type"; } } class A<T> { public function new () { } public function printName() { trace("Generic name: A"); } } class AA<T> extends A<T> { public function new () { super(); } override public function printName() { trace("Generic name AA"); } }是否有合法的方法来检查对象是否属于泛型类型?
I'm looking for a safe way to fork logic depending on the object type. I haven't found out how to check if an object belongs to a specific generic type.
class Test { static function main() { var aa = new AA<Int>(); //ERROR: Cast type parameters must be Dynamic //var a:A<Int> = cast(aa, A<Int>); //ERROR: Unexpected ) //var a:A<Int> = Std.instance(aa, A<Int>); //OK, but throw run-time exception with flash target. var a:A<Int> = cast aa; a.printName(); //Run-time exception a = cast "String is obviously wrong type"; } } class A<T> { public function new () { } public function printName() { trace("Generic name: A"); } } class AA<T> extends A<T> { public function new () { super(); } override public function printName() { trace("Generic name AA"); } }Is there a legal way to check if an object belongs to a generic type?
最满意答案
通常没有很好的方法可以做到这一点,因为信息在运行时不再可用。 您可以使用通常为Java建议的相同解决方法,即在类中存储泛型类型:
class Main { static function main() { var a = new A<Int>(Int); trace(a.typeParamIs(Int)); // true trace(a.typeParamIs(Bool)); // false } } class A<T> { var type:Any; public function new (type:Any) { this.type = type; } public function typeParamIs(type:Any):Bool { return this.type == type; } }或者,如果A有一个类型为T的字段,你可以像这样使用Type.typeOf() :
class Main { static function main() { checkType(new A<Int>(5)); // Int checkType(new A<Bool>(true)); // Bool checkType(new A<B>(new B())); // B checkType(new A<B>(null)); // unhandled type TNull } static function checkType<T>(a:A<T>) { trace(switch (Type.typeof(a.value)) { case TInt: "Int"; case TBool: "Bool"; case TClass(cls) if (cls == B): "B"; case other: throw "unhandled type " + other; }); } } class A<T> { public var value:T; public function new (value:T) { this.value = value; } } class B { public function new() {} }正如您所看到的,虽然这通常有效,但在某些情况下可能会导致意外行为 - 例如当value为null 。 还要记住Type.typeOf()的文档:
可能因平台而异。 应尽量减少对此的假设,以避免意外。
进一步阅读: 邮件列表线程已经讨论了一段时间。 如果您不需要在运行时知道类型,那么会提到宏解决方案。
There is generally no great way of doing this, because the information is not available at runtime anymore. You could use the same workaround that is often suggested for Java, which is storing the generic type in your class:
class Main { static function main() { var a = new A<Int>(Int); trace(a.typeParamIs(Int)); // true trace(a.typeParamIs(Bool)); // false } } class A<T> { var type:Any; public function new (type:Any) { this.type = type; } public function typeParamIs(type:Any):Bool { return this.type == type; } }Alternatively, you could use Type.typeOf() like this if A has a field of type T:
class Main { static function main() { checkType(new A<Int>(5)); // Int checkType(new A<Bool>(true)); // Bool checkType(new A<B>(new B())); // B checkType(new A<B>(null)); // unhandled type TNull } static function checkType<T>(a:A<T>) { trace(switch (Type.typeof(a.value)) { case TInt: "Int"; case TBool: "Bool"; case TClass(cls) if (cls == B): "B"; case other: throw "unhandled type " + other; }); } } class A<T> { public var value:T; public function new (value:T) { this.value = value; } } class B { public function new() {} }As you can see, while this usually works, it might lead to unexpected behavior in some cases - such as when value is null. Also keep in mind the docs of Type.typeOf():
May vary per platform. Assumptions regarding this should be minimized to avoid surprises.
Further reading: mailing list thread where this has been discussed a while back. A macro solution is mentioned there, in case you do not need to know the type at runtime.
更多推荐
发布评论