2011-09-07 101 views
4

由于.NET数组是协变的,在C#以下工作:阵列协方差

var strArray = new string[0]; 
object[] objArray = strArray; 

在F#中,给定一个数组,'T[],这将是将其转换为obj[]的最佳途径,而无需重新 - 创建数组(例如,Array.map box)?我使用(box >> unbox),但感觉马虎。

+3

有趣。我对C#不了解。这不是一个错误的特征,会危及静态安全吗? – wmeyer

+2

@wmeyer:http://stackoverflow.com/q/3516619/162396; http://blogs.msdn.com/b/ericlippert/archive/2007/10/17/covariance-and-contravariance-in-c-part-two-array-covariance.aspx – Daniel

+1

其实我觉得对于一般它非常有用实现非通用接口的类。 – Daniel

回答

3
box >> unbox 

似乎是一个好主意; O(1),显然是做这项工作。

考虑也不会使用这个CLR错功能。 ;)

+2

我想我可以使用'Array.map框',但是当完美的错误可用时重新创建数组感觉不对。 ;-) – Daniel

3

布赖恩的解决方案看起来好像没什么问题,但你真的需要阵列协方差?

如果你有一个函数,它ISomething[],并希望通过它SomeSomething[]那么你需要它,但如果功能只是从阵列读取ISomething类型的值(这是协方差允许的话),那么你可以使用哈希类型并编写一个需要#ISomething[]的函数。 (当然假设你可以修改该函数!)

这样,函数可以在实现ISomething的任何元素的数组上工作,并且在调用它时不需要数组协变。这里有一个例子:

type A() = 
    interface IDisposable with 
    member x.Dispose() = printfn "gone" 

// Disposes the first element from an array 
let disposeFirst (a:#IDisposable[]) = a.[0].Dispose() 

// Call 'disposeFirst' with 'A[]' as an argument 
let aa = [| new A(); new A() |] 
disposeFirst aa 

在我看来,对于在.NET阵列协方差的主要原因是,它需要在时泛型不存在的时候,但似乎F#生活中可以没有这个功能正好。

+0

你将如何实现一个接口成员返回'obj []'具有''T []'类型成员的泛型类型?接口不知道“T”,所以我没有看到哈希类型如何帮助。 – Daniel

+0

@丹尼尔 - 我不确定我是否理解这种情况。你能举一些例子吗?哈希类型,使功能通用,并允许其采取不只是'OBJ []'而且'富[]''那里从foo''obj'继承,这是同样的事情什么阵列协方差呢... –

+0

一个接口(不是泛型的)有一个'obj []'类型的成员。障碍在于使用散列类型会使封闭类型变得通用。实现接口*的类是* generic,但是(相应的成员的类型是''T []')。 – Daniel

4

正如Brian所说,box >> unbox没有什么问题,除了阵列协方差本质上已经损坏的事实(例如([| "test" |] |> box |> unbox<obj[]>).[0] <- obj()将在尝试执行赋值时抛出ArrayTypeMismatchException)。

相反,你可能会更好过治疗string[]作为obj seq,这是完全安全的(尽管它仍然需要在F#中,因为F#不支持泛型CO /禁忌方差装箱和拆箱)。不幸的是,如果你走这条路线,你会失去随机访问。

+0

不幸的是我需要随机访问。也许更大的问题是如何实现一个类型为数组的非泛型接口成员。我的界面是一个“页面列表项目”(项目加上分页信息)。所以数组元素可以是任何类型。否则,我会发明另一个接口来表示数组元素。我想这是首选的解决方案。 – Daniel

+1

@Daniel - 理想情况下,BCL将包含一个“ReadOnlyArray <'t>”类型,它是协变的并且是来自于的。由于它没有,你只限于一些不太理想的选择。使用数组协变是好的,只要你记得永远不要写入转换数组... – kvb

+2

我记录了ReadOnlyArray,请投票! http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2235515-readonly-array – Brian