簡體   English   中英

獲取序列的基礎類型(數組,列表,seq)

[英]Get underlying type for a sequence (array, list, seq)

給定一個type具有各種屬性,一個人如何當屬性是提取屬性的類型arraylistseq

示例代碼如下

type Car = { name: string }
type CarStore = 
    { name: string
    cars: Car[]
    names: string list
    others: string seq
    others2: ResizeArray<string> }

let peek x =
    Dump x
    x

let extractTypeInfo name (typ:Type) =
    let isEnumerable = true //todo: true for list, array, seq, etc
    let underlyingType = typ //todo: if isEnumerable = true, get actual type
    isEnumerable, underlyingType

typeof<CarStore>.GetProperties()
|> peek
|> Seq.map (fun p -> extractTypeInfo p.Name p.PropertyType)
|> Dump

執行以上屬性,

  • name: String
  • 汽車: IStructuralEquatable[]
  • names: FSharpList<String>
  • 其他: IEnumerable<String>
  • others2: List<String>

應該如何更新extractTypeInfo以便結果具有以下信息

  • name: String
  • 汽車: Car
  • names: String
  • 其他: String
  • others2: String

我傾向於做這樣的事情:

let extractTypeInfo (typ:Type) =
    typ.GetInterfaces()
    |> Array.tryFind (fun iFace -> 
        iFace.IsGenericType && iFace.GetGenericTypeDefinition() = typedefof<seq<_>>)
    |> Option.map (fun iFace -> iFace.GetGenericArguments().[0]) 

這種方法捕獲類型是否是seq<'T>通過返回SomeNone和類型'T的結果中Some情況下。

FSI中的一些例子:

 extractTypeInfo typeof<float array>;; val it : System.Type option = Some System.Double ... extractTypeInfo typeof<string list>;; val it : System.Type option = Some System.String ... extractTypeInfo typeof<int>;; val it : System.Type option = None 

@TheInnerLight的答案提供了一個很好的工作解決方案,但與往常一樣反思,你應該非常清楚你真正想要看到什么以及你真正關注的是什么。

我覺得這里有兩點值得注意:

  1. 雖然F#類型系統使數組看起來像正確的通用類型,但這並不是它們在.NET反射API中的表現。 給定一個數組類型,你會得到typ.IsGenericType等於false ,但是typ.IsArray等於true ,你可以使用typ.GetElementType()獲得type參數。 這是出於歷史原因,因為反射API早於.NET泛型。
  2. 您正在查看類型上的IEnumerable<'a>接口實現的泛型類型參數 - 僅在此處。 這意味着雖然類型和接口的泛型類型參數是相同的,但如果你只考慮列表,seqs和數組,在一般情況下它不是給定的。 您可以使用與其IEnumerable<'a>實現不同的類型參數實例化泛型類型(這是地圖和字典的情況),或者使用IEnumerable<'a>多個實現(在這種情況下,此解決方案將獲取它找到的第一個)。

這些可能不是您可能立即發現對您的解決方案重要的事情,但您可能會及時發現它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM