Actionscript 3 传递向量。<;T>;引用作为对象,强制转换导致创建副本

Actionscript 3 传递向量。<;T>;引用作为对象,强制转换导致创建副本,actionscript-3,vector,casting,Actionscript 3,Vector,Casting,我希望能作为推荐人传阅。现在,如果一个方法接受一个向量。,那么传递一个向量。,TRecord直接从对象继承的向量不起作用。其中一个方法只取普通对象;说vec:Object,然后可以传递向量。一旦进入该方法,需要在某个阶段执行显式强制转换,才能再次作为向量访问vec。不幸的是,一个cast似乎是一个副本,这意味着在多个Flex-ListCollectionViews中包装一个是没有用的;每个ListCollectionView将指向不同的向量 将数组与ArrayCollection一起使用不会出现

我希望能作为推荐人传阅。现在,如果一个方法接受一个
向量。
,那么传递一个
向量。
,TRecord直接从对象继承的向量不起作用。其中一个方法只取普通对象;说
vec:Object
,然后可以传递向量。一旦进入该方法,需要在某个阶段执行显式强制转换,才能再次作为向量访问
vec
。不幸的是,一个cast似乎是一个副本,这意味着在多个Flex-ListCollectionViews中包装一个是没有用的;每个ListCollectionView将指向不同的向量

将数组与ArrayCollection一起使用不会出现这样的问题,但我忽略了Vector的类型安全性、整洁性(代码应该足够干净,可以吃掉)和性能优势

有没有一种方法可以在不复制的情况下以通用的方式将它们转换或作为引用传递

注意:在本例中,IRecord是一个具有{r/w id:int&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);
}
受保护函数检查(srcVec:Object):无效
{
如果(!srcVec){
跟踪(“srcVec为空!”);
返回;
}
//srcVec=(@b347e21)
跟踪(srcVec.length);//4,如预期
var refVec:Vector.=Vector.(srcVec);
//refVec=(@bc781f1)
跟踪(refVec.length);//4,可以,但refVec的地址与srcVec不同
refVec.pop();
跟踪(refVec.length);//3正常
trace(srcVec.length);//4-清楚地创建了一个副本!!!
}
受保护的函数测试():void
{
变量vt1:向量。=新向量。//(@b347e21)-原始向量地址
变量vt2:Vector.=Vector.(vt1);/(@bbb57c1)-错误
变量vt3:Vector.=vt1作为向量。//(@null)-无法强制转换
变量vt4:Object=vt1;/(@b347e21)-良好
对于(变量ix:int=0;ix<4;ix++)
vt1.推动(新的三芯电缆);
if(vt1)跟踪(vt1.length);//4,如预期
if(vt2)跟踪(vt2.length);//0
如果(vt3)跟踪(vt3.length);//vt3为空
if(vt4)跟踪(vt4.length);//4
if(vt1)道(向量(vt1).length);//
跟踪(“呼叫检查(vt1)”;
检查(vt1);
}

这是不可能的。如果类型T与类型U是协变的,那么任何类型T的容器与类型U的容器都是不协变的。C#和Java使用内置数组类型实现了这一点,他们的设计人员希望他们可以返回并删除它

考虑一下,如果这个代码是合法的

var vt1: Vector.<IRecord> = new Vector.<IRecord>;  
var vt3: Vector.<Object> = vt1 as Vector.<Object>; 
但是等等——因为它实际上是
向量的一个实例。
,所以你不能这样做,即使
向量的契约明确规定你可以插入
对象。这就是为什么这种行为是明确不允许的


编辑:当然,您的框架可能会允许它成为此类文件的不可变引用,这是安全的。但我对ActionScript几乎没有经验,无法验证它是否真的有经验。

这是不可能的。如果类型T与类型U是协变的,那么任何类型T的容器与类型U的容器都是不协变的。C#和Java使用内置数组类型实现了这一点,他们的设计人员希望他们可以返回并删除它

考虑一下,如果这个代码是合法的

var vt1: Vector.<IRecord> = new Vector.<IRecord>;  
var vt3: Vector.<Object> = vt1 as Vector.<Object>; 
但是等等——因为它实际上是
向量的一个实例。
,所以你不能这样做,即使
向量的契约明确规定你可以插入
对象。这就是为什么这种行为是明确不允许的


编辑:当然,您的框架可能会允许它成为此类文件的不可变引用,这是安全的。但是我对ActionScript没有什么经验,无法验证它是否真的有用。

谢谢您的回复。所以这纯粹是一个接口与对象类相反的问题?无关:As3允许我将实现IRecord接口的对象推送到向量中。不过。为了使事情更简单,我将只使用向量。;可能没有那么干净,但是我可以使用一个包装器集合来处理正确的铸造(如果需要的话)。我希望能够创建一个通用的向量集合,但它看起来有问题。不过,用一些技巧是可行的;as3是一种非常灵活的语言。感谢您的回复。所以这纯粹是一个接口与对象类相反的问题?无关:As3允许我将实现IRecord接口的对象推送到向量中。不过。为了使事情更简单,我将只使用向量。;可能没有那么干净,但是我可以使用一个包装器集合来处理正确的铸造(如果需要的话)。我希望能够创建一个通用的向量集合,但它看起来有问题。不过,用一些技巧是可行的;as3是一种非常灵活的语言。