用反射发现属性失败
Failure to discover property with reflection
以下面的最小示例为例:
type IMyInterface =
interface
abstract member Name: string with get
end
let testInstance =
{ new IMyInterface with
member _.Name = "Hello Word" }
我本来天真地期望对 testInstance.GetType().GetProperties()
的调用包含一个 PropertyInfo
元素对应于 Name
.
但是,只返回一个空数组。
使用 testInstance.GetType().GetProperty("Name")
并没有更好的效果,因为它只是 returns 一个 <null>
对象。
更令人困惑的是,Visual Studio 2022 IntelliSense 将 Name
列为有效的 属性(如我所料)。
如何得到PropertyInfo
对应Name
属性?
在 F# 中,所有接口实现都是私有的。这意味着接口方法和属性不会作为实现的方法和属性出现 class.
在 C# 中,这有点不同:如果定义一个 public 成员恰好与接口成员匹配,则不必明确告诉编译器它是接口实现,编译器会自动为你映射到接口。
因此,例如,如果您这样写:
class MyClass : IMyInterface {
public string Name { get; }
}
C# 编译器实际上会这样编译它:
class MyClass : IMyInterface {
public string Name { get; }
string IMyInterface.Name { get { return this.Name; } }
}
(好吧,不完全是这样,但你明白了)
但 F# 编译器不这样做。如果你想要一个class 属性 除了界面属性,你还得自己滚一个:
type MyClass() =
member __.Name = "Hello Word"
interface IMyInterface with
member this.Name = this.Name
但如果你只想要接口 属性,你可以从接口类型中获取它:
let nameProp = typeof<IMyInterface>.GetProperty("Name")
let helloWorld = nameProp.GetValue testInstance
或者,如果事先不知道接口类型,也可以从对象类型中获取:
let intf = testInstance.GetType().GetInterfaces().[0]
let nameProp = intf.GetProperty("Name")
let helloWorld = nameProp.GetValue testInstance
以下面的最小示例为例:
type IMyInterface =
interface
abstract member Name: string with get
end
let testInstance =
{ new IMyInterface with
member _.Name = "Hello Word" }
我本来天真地期望对 testInstance.GetType().GetProperties()
的调用包含一个 PropertyInfo
元素对应于 Name
.
但是,只返回一个空数组。
使用 testInstance.GetType().GetProperty("Name")
并没有更好的效果,因为它只是 returns 一个 <null>
对象。
更令人困惑的是,Visual Studio 2022 IntelliSense 将 Name
列为有效的 属性(如我所料)。
如何得到PropertyInfo
对应Name
属性?
在 F# 中,所有接口实现都是私有的。这意味着接口方法和属性不会作为实现的方法和属性出现 class.
在 C# 中,这有点不同:如果定义一个 public 成员恰好与接口成员匹配,则不必明确告诉编译器它是接口实现,编译器会自动为你映射到接口。
因此,例如,如果您这样写:
class MyClass : IMyInterface {
public string Name { get; }
}
C# 编译器实际上会这样编译它:
class MyClass : IMyInterface {
public string Name { get; }
string IMyInterface.Name { get { return this.Name; } }
}
(好吧,不完全是这样,但你明白了)
但 F# 编译器不这样做。如果你想要一个class 属性 除了界面属性,你还得自己滚一个:
type MyClass() =
member __.Name = "Hello Word"
interface IMyInterface with
member this.Name = this.Name
但如果你只想要接口 属性,你可以从接口类型中获取它:
let nameProp = typeof<IMyInterface>.GetProperty("Name")
let helloWorld = nameProp.GetValue testInstance
或者,如果事先不知道接口类型,也可以从对象类型中获取:
let intf = testInstance.GetType().GetInterfaces().[0]
let nameProp = intf.GetProperty("Name")
let helloWorld = nameProp.GetValue testInstance