F#引用类型

时间:2013-11-23 20:22:56

标签: f#

我正在开发一个项目,其中F#代码将被其他.NET项目使用 - 所以我正在使用类。我创建了一个这样的代码文件:

namespace StockApplication

open System


type Stock = 
    {Symbol: String;
     DayOpen: Decimal;
     Price: Decimal;
     }

    member x.GetChange () =
        x.Price - x.DayOpen

    member x.GetPercentChange() =
        Math.Round(x.GetChange()/x.DayOpen,4)

当我从用C#编写的一些单元测试中使用它时,这很好用。例如:

[TestMethod]
public void CreateStock_ReturnsValidInstance()
{
    Stock stock = new Stock("TEST", 10, 10.25M);
    Assert.IsNotNull(stock);
}

然后我去另一个类创建另一个文件。这个类使用第一类,所以我确保它低于VS2012中的原始类。当我创建下一个课程时,我可以通过intellisense看到它。

namespace StockApplication


open System

type StockTicker() = 
    member x.GetStock () =
        StockApplication.Stock

然而,每一个新人或参考它都会给我同样的错误:

  

错误1值,构造函数,命名空间或类型“Stock”不是   定义

有没有人知道为什么我可以简单地在另一个F#文件中新建一个我在F#中创建的类?

提前致谢。

2 个答案:

答案 0 :(得分:3)

在没有问题的情况下编译的Stock stock = new Stock("TEST", 10, 10.25M);的C#测试提示相信Stock的F#构造函数应该看起来相同。但事实并非如此,也许是你混淆的根源。

你原来的

type Stock = 
    {Symbol: String;
     DayOpen: Decimal;
     Price: Decimal; }

确实是F#type Record,不是普通的类。以下来自MSDN的摘录适用:

  

记录结构也与班级建设不同。在记录类型中,您无法定义构造函数。

意思是

let stock = Stock("ABC"; 10M; 10M)

将生成error FS0039: The value or constructor 'Stock' is not defined

let stock = { Symbol = "ABC"; DayOpen = 10M; Price = 10M; }

将成功创建记录实例。

为了在第二个 F#类型Stock中构建StockTicker类型的实例,您应该使用记录构造语法,例如

member x.GetStock () = { Symbol = "MSFT"; DayOpen = 32M; Price = 32.5M; }

编译没有任何问题。

当谈到使用 C#的F#记录时,后者遵循您在测试方法中应用的语法。

答案 1 :(得分:2)

好的,在深入了解this引用(MSDN为0帮助)之后,我找到了答案。

以下是Stock类的语法:

namespace StockApplication

open System


type Stock = class
    val Symbol: String
    val DayOpen: Decimal
    val Price: Decimal

    new (symbol, dayOpen, price) =
        {
            Symbol = symbol;
            DayOpen = dayOpen;
            Price = price
        }

    member x.GetChange () =
        x.Price - x.DayOpen

    member x.GetPercentChange() =
        Math.Round(x.GetChange()/x.DayOpen,4)


end

以下是消费类的语法:

namespace StockApplication

type StockTicker() = 
    member x.GetStock () =
        let y = new Stock("AET",1m,1m)
        y.DayOpen