实例化类型:何时使用new?

时间:2011-02-13 14:23:21

标签: .net f# new-operator instantiation

我有一个在f#中映射类的类型,如下所示:

type MyClass =
   val myval: integer
   new () = {
      myval = 0;
   }
   member self.MyVal with
      get () = self.myval

好吧,我想创建这个类的实例。 我可以这样做:

let myinstance = MyClass ()

let myinstance = new MyClass ()

有什么区别? 我能同时做到吗?

3 个答案:

答案 0 :(得分:8)

从技术上讲,一个区别是你应该在创建new对象时使用IDisposable,因为nyinyithann已经解释过了。另一个区别是您可以在创建泛型类型时省略类型参数:

// Works and creates Dictionary<int, string>
let r1 = System.Collections.Generic.Dictionary 10 
r1.Add(10, "A")

// You get a compiler error when you write this:
let r2 = new System.Collections.Generic.Dictionary 10 
r2.Add(10, "A")

除了这两件事之外,没有任何技术差异(当您编写或省略new时,生成的IL肯定没有区别。)

你应该使用哪一个?这是一个风格问题。任何F#编码标准都没有涵盖这一点,因此这取决于您的偏好。现在我正在考虑它,我自己可能没有非常一致的风格。我认为在使用new创建要分配给值的实例时,我通常会使用let

let rnd = new Random()

但是,在创建要用作参数的对象时,我通常不会使用new(例如,在以下示例中为SizePoint):

let frm = new Form(Size = Size(600, 400))
let gr = frm.CreateGraphics()
gr.FillRectangle(Brushes.Red, Rectangle(Point(0, 0), Point(100, 100)))

可能,我也更喜欢将new用于更复杂的类型,并避免使用简单类型或.NET值类型(但我不认为我这样做过于一致)。

答案 1 :(得分:2)

对于实现IDisposable的类型,应使用new进行实例化。否则,您将收到以下编译警告。

建议使用“new Type(args)”而不是“Type(args)”创建支持IDisposable接口的对象,以指示资源可能由生成的值拥有

答案 2 :(得分:2)

没有区别。这两个调用都将创建一个具有完全相同IL代码的新对象。

.method public static void  main@() cil managed
{
  .entrypoint
  // Code size       26 (0x1a)
  .maxstack  4
  .locals init ([0] class Program/MyClass myinstance,
           [1] class Program/MyClass myinstance2)
  IL_0000:  nop
  IL_0001:  newobj     instance void Program/MyClass::.ctor()
  IL_0006:  dup
  IL_0007:  stsfld     class Program/MyClass '<StartupCode$fsharpapp>'.$Program::myinstance@11
  IL_000c:  stloc.0
  IL_000d:  newobj     instance void Program/MyClass::.ctor()
  IL_0012:  dup
  IL_0013:  stsfld     class Program/MyClass '<StartupCode$fsharpapp>'.$Program::myinstance2@12
  IL_0018:  stloc.1
  IL_0019:  ret
} // end of method $Program::main@

要反编译二进制文件,您可以使用.NET Framework SDK的ildasm,它在您打开Visual Studio命令提示符时位于路径中。

ildasm /CAVERBAL /out=fsharp.il fsharpapp.exe

选项CAVERBAL会以通常的方式打印人类可读形式的属性内容,而不是二进制blob。