2012-11-13 55 views
1

对于我的一个项目,我需要一个可以携带多种类型的列表,并且我不想进行任何投射,因此我尝试了使用obj list s。下面是一些示例代码来展示一些东西,应该工作,但由于某种原因没有:F#对象列表

type Fruit() = 
    member this.Kind = "I'm a tasty fruit!" 

type Apple() = 
    inherit Fruit() 
    member this.Kind = "I'm a crispy apple!" 

type Cherry() = 
    inherit Fruit() 
    member this.Kind = "I'm a juicy cherry!" 


> (new Fruit()).Kind 
val it : string = "I'm a tasty fruit!" 

... // And so on; it works as expected for all three fruits 

> let aFruit = [new Fruit()] 
val aFruit : Fruit list = [FSI_0002+Fruit] 

> aFruit.Head.Kind       // Works just fine 
val it : string = "I'm a tasty fruit!" 

> let fruits : obj list = [new Fruit(); new Apple(); new Cherry] 
val fruits : obj list = [FSI_0002+Fruit; FSI_0002+Apple; FSI_0002+Cherry] 

> fruits.Head        // Okay, so we can extract items just fine. It also kept the property! 
val it : obj = FSI_0002+Fruit {Kind = "I'm a tasty fruit!";} 

> it.Kind         // This doesn't work. Why? What am I missing? 
error FS0039: The field, constructor or member 'Kind' is not defined 
+0

应该不会是会员it.Kind?我个人不使用F#。只是一点点。 – bonCodigo

+0

这或它可以被称为任何东西;它的标识符到当前对象。 – Jwosty

回答

3

的问题是it的类型为obj的列表是一个obj listobj没有.Kind成员。您可以使用父类型 - 像

let fruits : Fruit list = [new Fruit(); new Apple(); new Cherry()];; 

val fruits : Fruit list = [FSI_0003+Fruit; FSI_0003+Apple; FSI_0003+Cherry] 

,然后用访问:

fruits.Head.Kind;; 
val it : string = "I'm a tasty fruit!" 
+0

哇,我以为我之前尝试过,但它并没有让我,因为苹果公司的一个实例并不是水果的一个实例......而且我认为,如果它确实起作用了,那么你不得不对它做出反应!我猜不会!此外,成员仍然工作,对吧? – Jwosty

+0

在某些情况下,你必须演员 - 但它只是'a:>水果'非常简单。成员显然工作得很好。 –

+1

哦,我实际上需要声明基本成员'abstract'然后'覆盖它它 – Jwosty