Types of creation: when using new ones?

I have a type matching class in f # as follows:

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

Well, I want to instantiate this class. I can do it:

 let myinstance = MyClass () 

or

 let myinstance = new MyClass () 

Who cares? Can i do both?

+4
source share
3 answers

For types that implement IDisposable, an instance must be created using the new one. Otherwise, you will receive the following compilation warning.

It is recommended that objects that support the IDisposable interface be created using "new Type (args)" rather than "Type (args)" to indicate that resources can belong to the generated value

+2
source

Technically, one difference is that when creating IDisposable objects, you should use new , as nyinyithann already explained. Another difference is that when creating a generic type, you can omit type arguments:

 // 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") 

Apart from these two things, there is no technical difference (and, of course, there is no difference in the generated IL when you write or omit new ).

Which one should be used when? This is a matter of style. This does not apply to F # coding standards, so it depends on your preference. Now that I think about it, I probably don't have the most consistent style. I think that I usually use new when creating instances that will be assigned values ​​with let :

 let rnd = new Random() 

However, I usually do not use new when creating objects that will be used as arguments (for example, Size or Point in the following example):

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

Perhaps I also prefer to use new for more complex types and avoid it for simple types or for .NET value types (but I don't think I'm doing this too consistently).

+8
source

There is no difference. Both calls will create a new object with exactly the same IL code.

 .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@ 

To decompile your binary, you can use the ildasm SDK.NET Framework, which is in your path when you open the Visual Studio command prompt.

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

The CAVERBAL parameter prints the contents of attributes in a form convenient for human perception, and not as binary drops, as usual.

+2
source

Source: https://habr.com/ru/post/1339553/


All Articles