我希望能够在周围传递Vectors作为参考。现在,如果方法采用Vector.<Object>
,则传递Vector.<TRecord>
,其中TRecord直接从Object继承,则不起作用。方法只需要简单的 Object ;说vec: Object
,然后传递Vector是可能的。进入此方法后,需要在某个阶段进行显式转换才能再次作为Vector访问vec
。不幸的是,一个演员似乎制作了一个副本,这意味着在多个Flex ListCollectionViews中包装一个是无用的;每个ListCollectionView都将指向另一个Vector。
使用带有ArrayCollection的数组不存在这样的问题,但是我输掉了类型安全性,整洁性(代码应该足够干净以便吃掉)和Vector的性能优势。
有没有办法在没有副本的情况下以通用的方式投射它们或将它们作为参考传递?
注意在这个例子中,IRecord是一个{r / w id:int&amp; amp; name:String}属性,但它可以是一个类,比如说TRecord {id:int; name:String}或任何其他可用类型。
protected function check(srcVec: Object): void
{
if (!srcVec) {
trace("srcVec is null!");
return;
}
// srcVec = (@b347e21)
trace(srcVec.length); // 4, as expected
var refVec: Vector.<Object> = Vector.<Object>(srcVec);
// refVec = (@bc781f1)
trace(refVec.length); // 4, ok, but refVec has a different address than srcVec
refVec.pop();
trace(refVec.length); // 3 ok
trace(srcVec.length); // 4 - A copy was clearly created!!!
}
protected function test(): void
{
var vt1: Vector.<IRecord> = new Vector.<IRecord>; // (@b347e21) - original Vector address
var vt2: Vector.<Object> = Vector.<Object>(vt1); // (@bbb57c1) - wrong
var vt3: Vector.<Object> = vt1 as Vector.<Object>; // (@null) - failure to cast
var vt4: Object = vt1; // (@b347e21) - good
for (var ix: int = 0; ix < 4; ix++)
vt1.push(new TRecord);
if (vt1) trace(vt1.length); // 4, as expected
if (vt2) trace(vt2.length); // 0
if (vt3) trace(vt3.length); // vt3 is null
if (vt4) trace(vt4.length); // 4
if (vt1) trace(Vector.<Object>(vt1).length); //
trace("calling check(vt1)");
check(vt1);
}
答案 0 :(得分:4)
这是不可能的。如果类型T与类型U协变,则T的任何容器与U类型的容器不协变.C#和Java使用内置数组类型执行此操作,并且他们的设计者希望他们可以返回并删除它。
如果此代码合法,请考虑
var vt1: Vector.<IRecord> = new Vector.<IRecord>;
var vt3: Vector.<Object> = vt1 as Vector.<Object>;
现在我们有一个Vector.<Object>
。但是等等 - 如果我们有一个对象的容器,那么我们肯定可以在其中粘贴一个对象 - 对吧?
vt3.push(new Object());
但等等 - 因为它实际上是Vector.<IRecord>
的一个实例,即使Vector.<Object>
的合同清楚地表明您可以插入Object
,也不能这样做。这就是明确不允许这种行为的原因。
编辑:当然,你的框架可能允许它成为一个非可变的引用, 是安全的。但我对ActionScript几乎没有经验,也无法验证它是否确实存在。