如何通过反射获取含指定成员的类型的默认成员值?
问题原因与解决方案
你遇到的NullReferenceException是因为Unchecked.defaultof<'x>对于引用类型(比如你定义的User记录)会返回null,调用实例成员时自然触发空引用异常。
解决方案1:改为静态成员(推荐)
既然你的memberName返回固定字符串,完全不需要依赖实例状态,直接改成静态成员即可避免实例创建问题:
type User = { user_id: int username: string email: string } with static member memberName = "woo" let inline GetMemberName< 'x when 'x: (static member memberName: string)> () = ((^x) : (static member memberName: string) ()) // 调用示例 GetMemberName<User> () // 返回 "woo"
解决方案2:保留实例成员,创建有效实例
如果必须保留实例成员,需要生成该类型的有效实例而非null。对于F#记录类型,可以用反射创建默认实例;对于类则需要确保其有默认构造函数:
open FSharp.Reflection let inline GetMemberName< 'x when 'x: (member memberName: string) and 'x: equality> () = let t = typeof<'x> let instance = if FSharpType.IsRecord(t) then // 为记录字段生成默认值并创建实例 let fields = FSharpType.GetRecordFields(t) let defaultVals = fields |> Array.map (fun f -> if f.FieldType.IsValueType then Activator.CreateInstance(f.FieldType) else null :> obj) FSharpValue.MakeRecord(t, defaultVals) :?> 'x else // 类类型需有默认构造函数 Activator.CreateInstance<'x>() // 调用实例成员 ((^x) : (member memberName: string) instance) // 测试用User类型 type User = { user_id: int username: string email: string } with member this.memberName = "woo" // 调用示例 GetMemberName<User> () // 返回 "woo"
内容的提问来源于stack exchange,提问作者Josh
相关产品推荐
相关产品推荐

