문제

For a project of mine, I need a list that can carry multiple types, and I don't want to do any casting, so I've tried using obj lists. Here's some example code to show something that should work, but for some reason doesn't:

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
도움이 되었습니까?

해결책

The problem is that it has type obj as the list is an obj list and obj has no .Kind member. You can use the parent type - like

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

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

and then access it with:

fruits.Head.Kind;;
val it : string = "I'm a tasty fruit!"
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top