6

I am filling some object's fields with data using reflection. As my object is of F# type, it has some Option fields. In case of option

property.SetValue(object, newValue)

reasonably fails, because it needs

property.SetValue(object, Some(newValue))

Hence, I am trying to find out if a property is of type Option. I can do it like this:

let isOption (p:PropertyInfo) = p.PropertyType.Name.StartsWith("FSharpOption")

But there must be some better way, must it not? And I must say it is strange to me that there's no method IsOption in FSharpType.

p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
Rustam
  • 1,766
  • 18
  • 34

1 Answers1

11

You can use something like this:

let isOption (p:PropertyInfo) = 
    p.PropertyType.IsGenericType &&
    p.PropertyType.GetGenericTypeDefinition() = typedefof<Option<_>>

Basically, GetGenericTypeDefinition returns the generic type of the property without any type parameters. And typedefof does something very similar, only using compile-time type information. In this case, it will return Option<>, without any parameters. You can then simply compare them to see if they are the same type.

p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
  • Thanks for the prompt reply. Could we write `typedefof – Rustam Dec 20 '13 at 04:43
  • I just found out that this solution works great, but only for properties of generic type; for non-generic properties it unfortunately throws InvalidOperationException. We can surely catch it and return false in exception handling branch, but becomes too complex as for me – Rustam Dec 20 '13 at 04:50
  • @Rustam Sorry, yes, that is an issue. See my updated answer for a better solution. – p.s.w.g Dec 20 '13 at 04:56