F# 属性,typeof 和“这不是常量表达式”

6

编辑:添加了一个更完整的例子,以澄清问题。

一些.NET属性需要一个Type类型的参数。在F#中如何声明这些参数?

例如,在C#中我们可以这样做:

[XmlInclude(typeof(Car))]
[XmlInclude(typeof(Truck))]
class Vehicle { }
class Car : Vehicle { }
class Truck : Vehicle { }

但是,在F#中以下代码:

[<XmlInclude(typeof<Car>)>]
[<XmlInclude(typeof<Truck>)>]
type Vehicle() = class end
type Car() = inherit Vehicle()
type Truck() = inherit Car()

...导致编译错误:这不是常量表达式或有效的自定义属性值。

2个回答

5

当属性中的类型前向使用时,您应该解决循环类型依赖。以下代码段展示了如何在F#中完成此操作:

// Compiles OK
[<AttributeUsage(AttributeTargets.All, AllowMultiple=true)>]
type XmlInclude(t:System.Type) =
   inherit System.Attribute()

[<XmlInclude(typeof<Car>)>]
[<XmlInclude(typeof<Truck>)>]
type Vehicle() = class end
and Car() = inherit Vehicle()
and Truck() = inherit Car()

2

你能否尝试提供一个更完整的示例以便查看出错信息?我刚刚快速地尝试了类似的东西,在Visual Studio 2012中的F# 3.0版本中可以正常运行:

type Car = C

type XmlInclude(typ:System.Type) =
  inherit System.Attribute()

[<XmlInclude(typeof<Car>)>]
let foo = 0

我想可能是某个微小的细节让F#编译器感到困惑了,但它应该理解typeof(实际上是一个函数)并允许在属性中使用。


感谢您确认这应该可以工作。当我尝试为您组合一个测试示例时,我发现问题不在于在属性中使用typeof<...>,而是CarTruck类在基类之后定义的问题。 - Wallace Kelly
2
@Wally 在这种情况下,您可能需要使用 type ... and ... 来定义递归类型(它们相互引用)。 - Tomas Petricek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接