2017-02-11 79 views
3

我正在寻找一种安全的方式来根据对象类型来分叉逻辑。我还没有发现如何检查对象是否属于特定的泛型类型。如何检查该对象是Haxe中泛型的实例

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"); 
    } 
} 

是否有合法的方法来检查对象是否属于泛型?

+0

我无法重现您在Flash上​​获得的运行时异常。另外,你的代码片段似乎缺少'B'的类型声明。 – Gama11

+0

你可以用SWF目标和调试flash播放器来查看http://try.haxe.org/#C6a93。 – kolonitsky

回答

4

这样做通常没有很好的方法,因为信息在运行时不再可用。你可以使用相同的解决方法是often suggested for 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; 
    } 
} 

或者,你可以使用Type.typeOf()这样如果AT类型的字段:

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() {} 
} 

正如您所看到的,虽然这通常可行,但在某些情况下可能会导致意外行为 - 例如valuenull。请记住Type.typeOf()的文档:

可能因平台而异。有关这方面的假设应尽量减少以避免意外。


进一步阅读:mailing list thread其中此已经讨论而回。在那里提到了一个宏观解决方案,如果你做而不是需要知道运行时的类型。

相关问题